create-colonel 0.1.5 → 0.1.7

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-colonel",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "colonel-app",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "scripts": {
@@ -8,7 +8,7 @@
8
8
  "upgrade:colonel": "bun add @coloneldev/framework@latest"
9
9
  },
10
10
  "dependencies": {
11
- "@coloneldev/framework": "^0.1.4",
11
+ "@coloneldev/framework": "^0.1.6",
12
12
  "ejs": "^5.0.1"
13
13
  },
14
14
  "devDependencies": {
@@ -1,132 +1,4 @@
1
- <section class="landing-shell">
2
- <style>
3
- @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');
4
-
5
- :root {
6
- --ink: #0d1310;
7
- --ink-soft: #203329;
8
- --canvas: #f3f1e9;
9
- --accent: #b8441a;
10
- --accent-soft: #db7c31;
11
- --panel: #ffffff;
12
- --olive: #5e6a39;
13
- --line: #d8d3c7;
14
- }
15
-
16
- body {
17
- margin: 0;
18
- background: radial-gradient(circle at 80% 10%, #f8e6c7 0%, var(--canvas) 38%, #ede8da 100%);
19
- color: var(--ink);
20
- font-family: 'Space Grotesk', sans-serif;
21
- }
22
-
23
- .landing-shell {
24
- max-width: 1040px;
25
- margin: 0 auto;
26
- padding: 2rem 1rem 3rem;
27
- }
28
-
29
- .hero {
30
- border: 1px solid var(--line);
31
- background: linear-gradient(125deg, #fffdf8 0%, #f6f3e9 100%);
32
- border-radius: 22px;
33
- padding: 2.2rem;
34
- box-shadow: 0 16px 45px rgba(32, 51, 41, 0.09);
35
- animation: rise 0.65s ease;
36
- }
37
-
38
- .kicker {
39
- font-family: 'IBM Plex Mono', monospace;
40
- letter-spacing: 0.1em;
41
- font-size: 0.74rem;
42
- color: var(--olive);
43
- margin-bottom: 1rem;
44
- }
45
-
46
- h1 {
47
- font-size: clamp(2rem, 5vw, 3.8rem);
48
- line-height: 1.03;
49
- margin: 0;
50
- max-width: 16ch;
51
- }
52
-
53
- .lead {
54
- margin-top: 1rem;
55
- font-size: 1.04rem;
56
- color: var(--ink-soft);
57
- max-width: 65ch;
58
- }
59
-
60
- .cta {
61
- display: flex;
62
- gap: 0.75rem;
63
- flex-wrap: wrap;
64
- margin-top: 1.4rem;
65
- }
66
-
67
- .btn {
68
- text-decoration: none;
69
- padding: 0.72rem 1.05rem;
70
- border-radius: 999px;
71
- font-weight: 600;
72
- border: 1px solid transparent;
73
- }
74
-
75
- .btn-primary {
76
- background: var(--accent);
77
- color: #fff;
78
- }
79
-
80
- .btn-secondary {
81
- border-color: var(--line);
82
- color: var(--ink);
83
- background: #fff;
84
- }
85
-
86
- .grid {
87
- margin-top: 1.25rem;
88
- display: grid;
89
- grid-template-columns: repeat(3, minmax(0, 1fr));
90
- gap: 0.8rem;
91
- }
92
-
93
- .tile {
94
- background: var(--panel);
95
- border: 1px solid var(--line);
96
- border-radius: 14px;
97
- padding: 0.95rem;
98
- }
99
-
100
- .tile strong {
101
- display: block;
102
- margin-bottom: 0.35rem;
103
- }
104
-
105
- .tile p {
106
- margin: 0;
107
- color: var(--ink-soft);
108
- font-size: 0.94rem;
109
- }
110
-
111
- .meta {
112
- margin-top: 1rem;
113
- font-family: 'IBM Plex Mono', monospace;
114
- font-size: 0.78rem;
115
- color: #4f5e54;
116
- }
117
-
118
- @keyframes rise {
119
- from { opacity: 0; transform: translateY(12px); }
120
- to { opacity: 1; transform: translateY(0); }
121
- }
122
-
123
- @media (max-width: 840px) {
124
- .hero { padding: 1.35rem; }
125
- .grid { grid-template-columns: 1fr; }
126
- }
127
- </style>
128
-
129
- <article class="hero">
1
+ <article class="surface">
130
2
  <div class="kicker">COLONEL // APP TEMPLATE</div>
131
3
  <h1>Your first Colonel app starts with opinionated clarity.</h1>
132
4
  <p class="lead">
@@ -134,7 +6,7 @@
134
6
  </p>
135
7
  <div class="cta">
136
8
  <a class="btn btn-primary" href="/users">View User Route</a>
137
- <a class="btn btn-secondary" href="https://github.com" target="_blank" rel="noreferrer">Open Documentation</a>
9
+ <a class="btn btn-secondary" href="<%= docsUrl || 'https://gwhitdev.github.io/colonel-framework/' %>" target="_blank" rel="noreferrer">Open Documentation</a>
138
10
  </div>
139
11
 
140
12
  <div class="grid">
@@ -153,5 +25,4 @@
153
25
  </div>
154
26
 
155
27
  <div class="meta">GENERATED WITH create-colonel • Runtime: Bun • Language: TypeScript</div>
156
- </article>
157
- </section>
28
+ </article>
@@ -4,10 +4,147 @@
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <link rel="icon" href="/favicon.png" sizes="any">
7
+ <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@400;600;700&family=IBM+Plex+Mono:wght@400;500&display=swap');
9
+
10
+ :root {
11
+ --ink: #0d1310;
12
+ --ink-soft: #203329;
13
+ --canvas: #f3f1e9;
14
+ --accent: #b8441a;
15
+ --accent-soft: #db7c31;
16
+ --panel: #ffffff;
17
+ --olive: #5e6a39;
18
+ --line: #d8d3c7;
19
+ }
20
+
21
+ * { box-sizing: border-box; }
22
+
23
+ body {
24
+ margin: 0;
25
+ background: radial-gradient(circle at 80% 10%, #f8e6c7 0%, var(--canvas) 38%, #ede8da 100%);
26
+ color: var(--ink);
27
+ font-family: 'Space Grotesk', sans-serif;
28
+ min-height: 100vh;
29
+ }
30
+
31
+ .page-shell {
32
+ max-width: 1040px;
33
+ margin: 0 auto;
34
+ padding: 2rem 1rem 3rem;
35
+ }
36
+
37
+ .surface {
38
+ border: 1px solid var(--line);
39
+ background: linear-gradient(125deg, #fffdf8 0%, #f6f3e9 100%);
40
+ border-radius: 22px;
41
+ padding: 2.2rem;
42
+ box-shadow: 0 16px 45px rgba(32, 51, 41, 0.09);
43
+ animation: rise 0.65s ease;
44
+ }
45
+
46
+ .kicker {
47
+ font-family: 'IBM Plex Mono', monospace;
48
+ letter-spacing: 0.1em;
49
+ font-size: 0.74rem;
50
+ color: var(--olive);
51
+ margin-bottom: 1rem;
52
+ }
53
+
54
+ h1 {
55
+ font-size: clamp(2rem, 5vw, 3.8rem);
56
+ line-height: 1.03;
57
+ margin: 0;
58
+ max-width: 16ch;
59
+ }
60
+
61
+ .lead {
62
+ margin-top: 1rem;
63
+ font-size: 1.04rem;
64
+ color: var(--ink-soft);
65
+ max-width: 65ch;
66
+ }
67
+
68
+ .cta {
69
+ display: flex;
70
+ gap: 0.75rem;
71
+ flex-wrap: wrap;
72
+ margin-top: 1.4rem;
73
+ }
74
+
75
+ .btn {
76
+ text-decoration: none;
77
+ padding: 0.72rem 1.05rem;
78
+ border-radius: 999px;
79
+ font-weight: 600;
80
+ border: 1px solid transparent;
81
+ display: inline-block;
82
+ }
83
+
84
+ .btn-primary {
85
+ background: var(--accent);
86
+ color: #fff;
87
+ }
88
+
89
+ .btn-secondary {
90
+ border-color: var(--line);
91
+ color: var(--ink);
92
+ background: #fff;
93
+ }
94
+
95
+ .meta {
96
+ margin-top: 1rem;
97
+ font-family: 'IBM Plex Mono', monospace;
98
+ font-size: 0.78rem;
99
+ color: #4f5e54;
100
+ }
101
+
102
+ .grid {
103
+ margin-top: 1.25rem;
104
+ display: grid;
105
+ grid-template-columns: repeat(3, minmax(0, 1fr));
106
+ gap: 0.8rem;
107
+ }
108
+
109
+ .tile {
110
+ background: var(--panel);
111
+ border: 1px solid var(--line);
112
+ border-radius: 14px;
113
+ padding: 0.95rem;
114
+ }
115
+
116
+ .tile strong {
117
+ display: block;
118
+ margin-bottom: 0.35rem;
119
+ }
120
+
121
+ .tile p {
122
+ margin: 0;
123
+ color: var(--ink-soft);
124
+ font-size: 0.94rem;
125
+ }
126
+
127
+ .list {
128
+ margin-top: 1rem;
129
+ padding-left: 1.1rem;
130
+ }
131
+
132
+ @keyframes rise {
133
+ from { opacity: 0; transform: translateY(12px); }
134
+ to { opacity: 1; transform: translateY(0); }
135
+ }
136
+
137
+ @media (max-width: 840px) {
138
+ .surface { padding: 1.35rem; }
139
+ .grid { grid-template-columns: 1fr; }
140
+ }
141
+ </style>
7
142
  <%- title %>
8
143
  </head>
9
144
  <body>
10
- <%- body %>
145
+ <main class="page-shell">
146
+ <%- body %>
147
+ <%- footer %>
148
+ </main>
11
149
  </body>
12
- <%- footer %>
13
150
  </html>
@@ -1,3 +1,3 @@
1
- <footer>
1
+ <footer class="meta">
2
2
  <%- footerData %>
3
3
  </footer>
@@ -1,13 +1,19 @@
1
- <html>
2
- <head>
3
- <title>Users</title>
4
- </head>
5
- <body>
6
- <h1>Users</h1>
7
- <ul>
8
- <% users.forEach(user => { %>
9
- <li><%= user.name %></li>
10
- <% }); %>
11
- </ul>
12
- </body>
13
- </html>
1
+ <section class="surface">
2
+ <div class="kicker">COLONEL // USERS</div>
3
+ <h1>Registered Users</h1>
4
+ <p class="lead">This page is served through grouped routes and rendered with the shared base layout.</p>
5
+
6
+ <ul class="list">
7
+ <% users.forEach(user => { %>
8
+ <li>
9
+ <strong><%= user.name %></strong><br>
10
+ <span><%= user.email %></span>
11
+ </li>
12
+ <% }); %>
13
+ </ul>
14
+
15
+ <div class="cta">
16
+ <a class="btn btn-secondary" href="/">Back Home</a>
17
+ <a class="btn btn-primary" href="/users/1">View User #1</a>
18
+ </div>
19
+ </section>
@@ -0,0 +1,18 @@
1
+ <section class="surface">
2
+ <div class="kicker">COLONEL // USERS</div>
3
+ <h1><%= user.name %></h1>
4
+ <p class="lead">This page is served through grouped routes and rendered with the shared base layout.</p>
5
+
6
+ <ul class="list" style="list-style-type: none;">
7
+ <li>
8
+ <strong>Name: <%= user.name %></strong><br>
9
+ </li>
10
+ <li>
11
+ <span>Email: <%= user.email || 'Not provided' %></span>
12
+ </li>
13
+ </ul>
14
+
15
+ <div class="cta">
16
+ <a class="btn btn-secondary" href="/">Back Home</a>
17
+ </div>
18
+ </section>
@@ -1,3 +1,4 @@
1
+ import type { HttpRequest } from "@coloneldev/framework";
1
2
  import Controller from './Controller';
2
3
  import { AppInfoService } from '../../Services/AppInfoService';
3
4
 
@@ -8,12 +9,17 @@ export class AppController extends Controller {
8
9
  super();
9
10
  }
10
11
 
11
- index(): Record<string, any> {
12
+ index(req: HttpRequest): Record<string, any> {
13
+ const previousVisits = this.sessionGet<number>(req, "visits") ?? 0;
14
+ const visits = previousVisits + 1;
15
+ this.sessionPut(req, "visits", visits);
16
+
12
17
  return [
13
18
  'base/index',
14
19
  {
15
20
  "titleData": this.appInfoService.welcomeTitle(),
16
-
21
+ "docsUrl": this.appInfoService.documentationUrl(),
22
+ "footerData": `Session visits: ${visits}`,
17
23
  },
18
24
  ]
19
25
  }
@@ -1,3 +1,5 @@
1
+ import type { HttpRequest, Session } from "@coloneldev/framework";
2
+
1
3
  export default class Controller {
2
4
  constructor() {
3
5
  // Base constructor logic can be added here if needed
@@ -6,4 +8,24 @@ export default class Controller {
6
8
  health(): Record<string, string> {
7
9
  return { status: "ok" };
8
10
  }
11
+
12
+ protected requireSession(req: HttpRequest): Session {
13
+ if (!req.session) {
14
+ throw new Error("Session is not enabled for this request");
15
+ }
16
+
17
+ return req.session;
18
+ }
19
+
20
+ protected sessionGet<T = unknown>(req: HttpRequest, key: string): T | undefined {
21
+ return this.requireSession(req).get<T>(key);
22
+ }
23
+
24
+ protected sessionPut(req: HttpRequest, key: string, value: unknown): void {
25
+ this.requireSession(req).set(key, value);
26
+ }
27
+
28
+ protected sessionForget(req: HttpRequest, key: string): void {
29
+ this.requireSession(req).forget(key);
30
+ }
9
31
  }
@@ -6,14 +6,26 @@ export class UserController extends Controller {
6
6
  index(): Array<string | Record<string, any>> {
7
7
  return [
8
8
  'users/index',
9
- { users: [{ id: 1, name: "John Doe" }, { id: 2, name: "Jane Doe" }] }
9
+ {
10
+ users: [
11
+ { id: 1, name: "John Doe", email: "john@example.com" },
12
+ { id: 2, name: "Jane Doe", email: "jane@example.com" }
13
+ ]
14
+ }
10
15
  ]}
11
16
 
12
- show(req: HttpRequest): Record<string, string> {
17
+ show(req: HttpRequest): Array<string | Record<string, any>> {
13
18
  const id = req.params("id");
14
19
 
15
- return {
16
- "message": `Hello from UserController@show with id ${id}`
17
- }
20
+ return [
21
+ 'users/show',
22
+ {
23
+ user: {
24
+ id,
25
+ name: `User ${id}`,
26
+ email: `user${id}@example.com`
27
+ }
28
+ }
29
+ ]
18
30
  }
19
31
  }
@@ -1,7 +1,14 @@
1
1
  export class AppInfoService {
2
- constructor(private appName: string) {}
2
+ constructor(
3
+ private appName: string,
4
+ private docsUrl: string = "https://gwhitdev.github.io/colonel-framework/"
5
+ ) {}
3
6
 
4
7
  welcomeTitle(): string {
5
8
  return `Welcome to ${this.appName}`;
6
9
  }
10
+
11
+ documentationUrl(): string {
12
+ return this.docsUrl;
13
+ }
7
14
  }
@@ -13,11 +13,20 @@ const publicRoot = path.resolve(import.meta.dir, "..", "..", "public");
13
13
  const controllerRoot = path.resolve(import.meta.dir, "..", "app", "Http", "Controllers");
14
14
  const container = new Container();
15
15
 
16
- container.singleton(AppInfoService, () => new AppInfoService(process.env.appName ?? "Colonel"));
16
+ container.singleton(
17
+ AppInfoService,
18
+ () => new AppInfoService(
19
+ process.env.appName ?? "Colonel",
20
+ process.env.COLONEL_DOCS_URL ?? "https://gwhitdev.github.io/colonel-framework/"
21
+ )
22
+ );
17
23
 
18
24
  export const server = () => {
19
25
  const Colonel = new Kernel(webRouter, [], {
20
26
  viewsRoot,
27
+ session: {
28
+ enabled: true,
29
+ },
21
30
  controllerResolver: async (name: string) => {
22
31
  const modulePath = `${controllerRoot}/${name}.ts`;
23
32
  const mod = await import(modulePath);
@@ -6,16 +6,13 @@ const web = new Router();
6
6
  web.get('/favicon.ico', () => redirect('/favicon.png', 301));
7
7
 
8
8
  // Define your web routes here
9
- //web.get('/health', 'AppController@health');
10
9
  web.get('/health', () => new Response("OK", { status: 200 }));
11
10
 
12
11
  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');
12
+
13
+ web.group('/users', (users) => {
14
+ users.get('/', 'UserController@index');
15
+ users.get('/:id', 'UserController@show');
16
+ });
20
17
 
21
18
  export default web;