@donkeylabs/cli 1.1.10 → 1.1.12

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": "@donkeylabs/cli",
3
- "version": "1.1.10",
3
+ "version": "1.1.12",
4
4
  "type": "module",
5
5
  "description": "CLI for @donkeylabs/server - project scaffolding and code generation",
6
6
  "main": "./src/index.ts",
@@ -31,6 +31,7 @@
31
31
  "clsx": "^2.1.1",
32
32
  "kysely": "^0.27.6",
33
33
  "kysely-bun-sqlite": "^0.3.2",
34
+ "runed": "^0.23.4",
34
35
  "tailwind-merge": "^3.4.0",
35
36
  "tailwind-variants": "^3.2.2",
36
37
  "zod": "^3.24.0"
@@ -6,6 +6,7 @@ import { Database } from "bun:sqlite";
6
6
  import { demoPlugin } from "./plugins/demo";
7
7
  import { workflowDemoPlugin } from "./plugins/workflow-demo";
8
8
  import demoRoutes from "./routes/demo";
9
+ import { exampleRouter } from "./routes/example";
9
10
 
10
11
  // Simple in-memory database
11
12
  const db = new Kysely<{}>({
@@ -27,6 +28,7 @@ server.registerPlugin(workflowDemoPlugin);
27
28
 
28
29
  // Register routes
29
30
  server.use(demoRoutes);
31
+ server.use(exampleRouter);
30
32
 
31
33
  // Handle CLI type generation (must be after routes are registered)
32
34
  server.handleGenerateMode();
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+
3
+ // =============================================================================
4
+ // GREETING SCHEMAS
5
+ // =============================================================================
6
+
7
+ export const greetInputSchema = z.object({
8
+ name: z.string().min(1, "Name is required"),
9
+ formal: z.boolean().optional().default(false),
10
+ });
11
+
12
+ export const greetOutputSchema = z.object({
13
+ message: z.string(),
14
+ timestamp: z.string(),
15
+ });
16
+
17
+ // =============================================================================
18
+ // DERIVED TYPES
19
+ // =============================================================================
20
+
21
+ export type GreetInput = z.infer<typeof greetInputSchema>;
22
+ export type GreetOutput = z.infer<typeof greetOutputSchema>;
@@ -0,0 +1,23 @@
1
+ import type { Handler, Routes, AppContext } from "$server/api";
2
+
3
+ /**
4
+ * Greet Handler
5
+ *
6
+ * Example handler demonstrating the feature module pattern.
7
+ * Business logic lives directly in the handler - no separate model layer needed.
8
+ */
9
+ export class GreetHandler implements Handler<Routes.Example.Greet> {
10
+ constructor(private ctx: AppContext) {}
11
+
12
+ handle(input: Routes.Example.Greet.Input): Routes.Example.Greet.Output {
13
+ // Business logic directly in handler
14
+ const greeting = input.formal
15
+ ? `Good day, ${input.name}. How may I assist you?`
16
+ : `Hey ${input.name}!`;
17
+
18
+ return {
19
+ message: greeting,
20
+ timestamp: new Date().toISOString(),
21
+ };
22
+ }
23
+ }
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Example Router - Demonstrates the feature module pattern
3
+ *
4
+ * Feature modules organize app-specific routes with:
5
+ * - Thin router (just wiring)
6
+ * - Handler classes with business logic
7
+ * - Schemas in separate file
8
+ *
9
+ * Structure:
10
+ * routes/example/
11
+ * ├── index.ts <- Router (this file)
12
+ * ├── example.schemas.ts <- Zod schemas + types
13
+ * └── handlers/
14
+ * └── greet.handler.ts <- Handler with business logic
15
+ */
16
+
17
+ import { createRouter } from "@donkeylabs/server";
18
+ import { greetInputSchema, greetOutputSchema } from "./example.schemas";
19
+ import { GreetHandler } from "./handlers/greet.handler";
20
+
21
+ export const exampleRouter = createRouter("example")
22
+
23
+ // Simple greeting route
24
+ .route("greet").typed({
25
+ input: greetInputSchema,
26
+ output: greetOutputSchema,
27
+ handle: GreetHandler,
28
+ });