create-colonel 0.1.7 → 1.0.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 CHANGED
@@ -10,17 +10,17 @@ Scaffold a new Colonel app from the command line.
10
10
  ## Usage
11
11
 
12
12
  ```bash
13
- bun create colonel my-app
13
+ bunx create-colonel my-app
14
14
  ```
15
15
 
16
- Alternative entry points:
16
+ Optional flag:
17
17
 
18
18
  ```bash
19
- bunx create-colonel my-app
20
- npx create-colonel my-app
21
- npm create colonel@latest my-app
19
+ bunx create-colonel my-app --skip-install
22
20
  ```
23
21
 
22
+ Use `--skip-install` when you only want scaffolded files and prefer to install dependencies later.
23
+
24
24
  Then run your new app:
25
25
 
26
26
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-colonel",
3
- "version": "0.1.7",
3
+ "version": "1.0.1",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "src",
package/src/cli.ts CHANGED
@@ -3,10 +3,20 @@
3
3
  import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
4
4
  import { basename, resolve } from "node:path";
5
5
 
6
- const targetArg = process.argv[2];
6
+ const args = process.argv.slice(2);
7
+ const targetArg = args.find((arg) => !arg.startsWith("-"));
8
+ const skipInstall = args.includes("--skip-install");
9
+ const showHelp = args.includes("--help") || args.includes("-h");
10
+
11
+ if (showHelp) {
12
+ console.log("Usage: bunx create-colonel <project-name> [--skip-install]");
13
+ console.log("\nOptions:");
14
+ console.log(" --skip-install Scaffold files without running bun install");
15
+ process.exit(0);
16
+ }
7
17
 
8
18
  if (!targetArg) {
9
- console.error("Usage: bun create colonel <project-name>");
19
+ console.error("Usage: bunx create-colonel <project-name> [--skip-install]");
10
20
  process.exit(1);
11
21
  }
12
22
 
@@ -36,18 +46,25 @@ if (existsSync(resolve(localFrameworkPath, "package.json"))) {
36
46
 
37
47
  writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}\n`);
38
48
 
39
- console.log("Installing dependencies...");
40
- const install = Bun.spawnSync(["bun", "install"], {
41
- cwd: targetDir,
42
- stdout: "inherit",
43
- stderr: "inherit",
44
- });
49
+ if (!skipInstall) {
50
+ console.log("Installing dependencies...");
51
+ const install = Bun.spawnSync(["bun", "install"], {
52
+ cwd: targetDir,
53
+ stdout: "inherit",
54
+ stderr: "inherit",
55
+ });
45
56
 
46
- if (install.exitCode !== 0) {
47
- console.error("Project was created, but dependency installation failed.");
48
- process.exit(install.exitCode);
57
+ if (install.exitCode !== 0) {
58
+ console.error("Project was created, but dependency installation failed.");
59
+ process.exit(install.exitCode);
60
+ }
49
61
  }
50
62
 
51
63
  console.log("\nColonel app created successfully.\n");
52
64
  console.log(` cd ${targetArg}`);
65
+
66
+ if (skipInstall) {
67
+ console.log(" bun install");
68
+ }
69
+
53
70
  console.log(" bun run start\n");
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "colonel-app",
3
- "version": "0.1.5",
3
+ "version": "1.0.1",
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.6",
11
+ "@coloneldev/framework": "^1.0.1",
12
12
  "ejs": "^5.0.1"
13
13
  },
14
14
  "devDependencies": {
@@ -1,4 +1,4 @@
1
- import type { HttpRequest } from "@coloneldev/framework";
1
+ import { json, type HttpRequest } from "@coloneldev/framework";
2
2
  import Controller from "./Controller";
3
3
 
4
4
 
@@ -28,4 +28,23 @@ export class UserController extends Controller {
28
28
  }
29
29
  ]
30
30
  }
31
+
32
+ create(req: HttpRequest): Response {
33
+ const payload = req.validate({
34
+ name: { required: true, type: "string", minLength: 2, maxLength: 80 },
35
+ email: {
36
+ required: true,
37
+ type: "string",
38
+ pattern: /^[^@\s]+@[^@\s]+\.[^@\s]+$/,
39
+ },
40
+ });
41
+
42
+ return json({
43
+ message: "User payload accepted",
44
+ user: {
45
+ name: payload.name,
46
+ email: payload.email,
47
+ },
48
+ }, 201);
49
+ }
31
50
  }
@@ -0,0 +1,11 @@
1
+ import { badRequest, type HttpRequest } from "@coloneldev/framework";
2
+
3
+ export async function requireJsonForWrites(req: HttpRequest, next: () => Promise<unknown>): Promise<unknown> {
4
+ if (["POST", "PUT", "PATCH", "DELETE"].includes(req.method) && !req.isJson()) {
5
+ return badRequest("Write requests must use application/json", {
6
+ hint: "Set Content-Type: application/json",
7
+ });
8
+ }
9
+
10
+ return next();
11
+ }
@@ -0,0 +1,18 @@
1
+ import type { HttpRequest } from "@coloneldev/framework";
2
+
3
+ export async function traceHeader(req: HttpRequest, next: () => Promise<unknown>): Promise<unknown> {
4
+ const result = await next();
5
+
6
+ if (!(result instanceof Response)) {
7
+ return result;
8
+ }
9
+
10
+ const headers = new Headers(result.headers);
11
+ headers.set("x-colonel-trace", `${req.method} ${req.path()}`);
12
+
13
+ return new Response(result.body, {
14
+ status: result.status,
15
+ statusText: result.statusText,
16
+ headers,
17
+ });
18
+ }
@@ -7,6 +7,8 @@ import { staticPaths } from "../config/staticPaths";
7
7
  import path, { extname } from "path";
8
8
  import { Container } from "@coloneldev/framework";
9
9
  import { AppInfoService } from "../app/Services/AppInfoService.ts";
10
+ import { requireJsonForWrites } from "../app/Http/Middleware/RequireJsonForWrites.ts";
11
+ import { traceHeader } from "../app/Http/Middleware/TraceHeader.ts";
10
12
 
11
13
  const viewsRoot = path.resolve(import.meta.dir, "..", "..", "resources", "views");
12
14
  const publicRoot = path.resolve(import.meta.dir, "..", "..", "public");
@@ -22,7 +24,10 @@ container.singleton(
22
24
  );
23
25
 
24
26
  export const server = () => {
25
- const Colonel = new Kernel(webRouter, [], {
27
+ const Colonel = new Kernel(webRouter, [
28
+ requireJsonForWrites,
29
+ traceHeader,
30
+ ], {
26
31
  viewsRoot,
27
32
  session: {
28
33
  enabled: true,
@@ -13,6 +13,7 @@ web.get('/', 'AppController@index');
13
13
  web.group('/users', (users) => {
14
14
  users.get('/', 'UserController@index');
15
15
  users.get('/:id', 'UserController@show');
16
+ users.post('/', 'UserController@create');
16
17
  });
17
18
 
18
19
  export default web;