deploy-bbc 0.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.
Files changed (127) hide show
  1. package/CLAUDE.md +329 -0
  2. package/README.md +0 -0
  3. package/cli/README.md +0 -0
  4. package/cli/package.json +43 -0
  5. package/cli/src/cli/index.ts +449 -0
  6. package/cli/src/helpers/create-project.ts +66 -0
  7. package/cli/src/helpers/generate-docker-compose.ts +133 -0
  8. package/cli/src/helpers/generate-dockerfile.ts +45 -0
  9. package/cli/src/helpers/init-git.ts +33 -0
  10. package/cli/src/helpers/install-dependencies.ts +28 -0
  11. package/cli/src/helpers/log-next-steps.ts +84 -0
  12. package/cli/src/helpers/scaffold-project.ts +62 -0
  13. package/cli/src/index.ts +18 -0
  14. package/cli/src/installers/ai.ts +123 -0
  15. package/cli/src/installers/auth.ts +132 -0
  16. package/cli/src/installers/base.ts +16 -0
  17. package/cli/src/installers/cloud.ts +127 -0
  18. package/cli/src/installers/database.ts +212 -0
  19. package/cli/src/installers/docs.ts +93 -0
  20. package/cli/src/installers/email.ts +119 -0
  21. package/cli/src/installers/env-variables.ts +27 -0
  22. package/cli/src/installers/index.ts +145 -0
  23. package/cli/src/installers/observability.ts +103 -0
  24. package/cli/src/installers/queue.ts +103 -0
  25. package/cli/src/installers/ratelimit.ts +98 -0
  26. package/cli/src/installers/realtime.ts +79 -0
  27. package/cli/src/installers/testing.ts +88 -0
  28. package/cli/src/installers/validation.ts +85 -0
  29. package/cli/src/templates/base/.env.example +3 -0
  30. package/cli/src/templates/base/README.md +31 -0
  31. package/cli/src/templates/base/package.json +20 -0
  32. package/cli/src/templates/base/src/config/index.ts +8 -0
  33. package/cli/src/templates/base/src/index.ts +26 -0
  34. package/cli/src/templates/base/src/middleware/error.ts +13 -0
  35. package/cli/src/templates/base/src/middleware/logger.ts +8 -0
  36. package/cli/src/templates/base/src/routes/index.ts +12 -0
  37. package/cli/src/templates/base/src/types/index.ts +2 -0
  38. package/cli/src/templates/base/src/utils/env.ts +5 -0
  39. package/cli/src/templates/base/tsconfig.json +20 -0
  40. package/cli/src/templates/base-bun-native/.env.example +3 -0
  41. package/cli/src/templates/base-bun-native/README.md +31 -0
  42. package/cli/src/templates/base-bun-native/package.json +19 -0
  43. package/cli/src/templates/base-bun-native/src/config/index.ts +8 -0
  44. package/cli/src/templates/base-bun-native/src/index.ts +50 -0
  45. package/cli/src/templates/base-bun-native/src/middleware/error.ts +20 -0
  46. package/cli/src/templates/base-bun-native/src/middleware/logger.ts +6 -0
  47. package/cli/src/templates/base-bun-native/src/routes/index.ts +21 -0
  48. package/cli/src/templates/base-bun-native/src/types/index.ts +2 -0
  49. package/cli/src/templates/base-bun-native/src/utils/env.ts +5 -0
  50. package/cli/src/templates/base-bun-native/tsconfig.json +20 -0
  51. package/cli/src/templates/base-express/.env.example +3 -0
  52. package/cli/src/templates/base-express/README.md +31 -0
  53. package/cli/src/templates/base-express/package.json +21 -0
  54. package/cli/src/templates/base-express/src/config/index.ts +8 -0
  55. package/cli/src/templates/base-express/src/index.ts +27 -0
  56. package/cli/src/templates/base-express/src/middleware/error.ts +15 -0
  57. package/cli/src/templates/base-express/src/middleware/logger.ts +12 -0
  58. package/cli/src/templates/base-express/src/routes/index.ts +12 -0
  59. package/cli/src/templates/base-express/src/types/index.ts +2 -0
  60. package/cli/src/templates/base-express/src/utils/env.ts +5 -0
  61. package/cli/src/templates/base-express/tsconfig.json +20 -0
  62. package/cli/src/templates/extras/ai/anthropic/src/routes/ai/claude.ts +0 -0
  63. package/cli/src/templates/extras/ai/anthropic/src/services/ai/anthropic.ts +0 -0
  64. package/cli/src/templates/extras/ai/gemini/src/services/ai/gemini.ts +0 -0
  65. package/cli/src/templates/extras/ai/openai/src/routes/ai/chat.ts +0 -0
  66. package/cli/src/templates/extras/ai/openai/src/services/ai/openai.ts +0 -0
  67. package/cli/src/templates/extras/ai/vercel-ai/src/routes/ai/generate.ts +0 -0
  68. package/cli/src/templates/extras/ai/vercel-ai/src/routes/ai/stream.ts +0 -0
  69. package/cli/src/templates/extras/ai/vercel-ai/src/services/ai/index.ts +0 -0
  70. package/cli/src/templates/extras/auth/jwt/src/middleware/auth.ts +0 -0
  71. package/cli/src/templates/extras/auth/jwt/src/routes/auth.ts +0 -0
  72. package/cli/src/templates/extras/auth/jwt/src/utils/jwt.ts +0 -0
  73. package/cli/src/templates/extras/auth/oauth/src/config/oauth.ts +0 -0
  74. package/cli/src/templates/extras/auth/oauth/src/routes/auth.ts +0 -0
  75. package/cli/src/templates/extras/auth/session/src/config/session.ts +0 -0
  76. package/cli/src/templates/extras/auth/session/src/middleware/session.ts +0 -0
  77. package/cli/src/templates/extras/cloud/aws/src/services/aws/s3.ts +0 -0
  78. package/cli/src/templates/extras/cloud/aws/src/services/aws/ses.ts +0 -0
  79. package/cli/src/templates/extras/cloud/azure/src/services/azure/blob.ts +0 -0
  80. package/cli/src/templates/extras/cloud/cloudflare-r2/src/services/cloudflare/r2.ts +0 -0
  81. package/cli/src/templates/extras/cloud/gcp/src/services/gcp/storage.ts +0 -0
  82. package/cli/src/templates/extras/database/mongodb/src/db/index.ts +0 -0
  83. package/cli/src/templates/extras/database/mongodb/src/db/models/user.model.ts +0 -0
  84. package/cli/src/templates/extras/database/mysql/drizzle.config.ts +0 -0
  85. package/cli/src/templates/extras/database/postgres/src/db/index.ts +0 -0
  86. package/cli/src/templates/extras/database/redis/src/db/redis.ts +0 -0
  87. package/cli/src/templates/extras/docs/scalar/src/openapi/index.ts +0 -0
  88. package/cli/src/templates/extras/docs/scalar/src/routes/docs.ts +0 -0
  89. package/cli/src/templates/extras/docs/swagger/src/openapi/index.ts +0 -0
  90. package/cli/src/templates/extras/docs/swagger/src/routes/docs.ts +0 -0
  91. package/cli/src/templates/extras/email/nodemailer/src/services/email/nodemailer.ts +0 -0
  92. package/cli/src/templates/extras/email/resend/src/services/email/resend.ts +0 -0
  93. package/cli/src/templates/extras/email/resend/src/templates/email/welcome.ts +0 -0
  94. package/cli/src/templates/extras/email/sendgrid/src/services/email/sendgrid.ts +0 -0
  95. package/cli/src/templates/extras/observability/logtail/src/config/logger.ts +0 -0
  96. package/cli/src/templates/extras/observability/sentry/src/config/sentry.ts +0 -0
  97. package/cli/src/templates/extras/observability/sentry/src/middleware/sentry.ts +0 -0
  98. package/cli/src/templates/extras/queue/bullmq/src/queue/index.ts +0 -0
  99. package/cli/src/templates/extras/queue/bullmq/src/queue/jobs/email.job.ts +0 -0
  100. package/cli/src/templates/extras/queue/bullmq/src/queue/processors/email.processor.ts +0 -0
  101. package/cli/src/templates/extras/queue/bullmq/src/routes/queue.ts +0 -0
  102. package/cli/src/templates/extras/queue/inngest/src/inngest/client.ts +0 -0
  103. package/cli/src/templates/extras/queue/inngest/src/inngest/functions/email.ts +0 -0
  104. package/cli/src/templates/extras/queue/inngest/src/routes/inngest.ts +0 -0
  105. package/cli/src/templates/extras/realtime/socketio/src/socket/handlers.ts +0 -0
  106. package/cli/src/templates/extras/realtime/socketio/src/socket/index.ts +0 -0
  107. package/cli/src/templates/extras/realtime/sse/src/routes/sse.ts +0 -0
  108. package/cli/src/templates/extras/testing/vitest/src/__tests__/example.test.ts +0 -0
  109. package/cli/src/templates/extras/testing/vitest/src/__tests__/setup.ts +0 -0
  110. package/cli/src/templates/extras/testing/vitest/vitest.config.ts +0 -0
  111. package/cli/src/templates/extras/validation/yup/src/middleware/index.ts +1 -0
  112. package/cli/src/templates/extras/validation/yup/src/middleware/validate.ts +83 -0
  113. package/cli/src/templates/extras/validation/yup/src/routes/users.ts +132 -0
  114. package/cli/src/templates/extras/validation/zod/src/middleware/index.ts +1 -0
  115. package/cli/src/templates/extras/validation/zod/src/middleware/validate.ts +80 -0
  116. package/cli/src/templates/extras/validation/zod/src/routes/users.ts +128 -0
  117. package/cli/src/types/index.ts +126 -0
  118. package/cli/src/utils/add-package-dependency.ts +56 -0
  119. package/cli/src/utils/dependency-version-map.ts +85 -0
  120. package/cli/src/utils/logger.ts +19 -0
  121. package/cli/src/utils/parse-name-and-path.ts +55 -0
  122. package/cli/src/utils/render-title.ts +11 -0
  123. package/cli/tsconfig.json +35 -0
  124. package/package.json +20 -0
  125. package/prettier.config.mjs +0 -0
  126. package/test-cli.sh +56 -0
  127. package/tsconfig.json +15 -0
@@ -0,0 +1,50 @@
1
+ import { config } from "./config/index.js";
2
+ import { logger } from "./middleware/logger.js";
3
+ import { errorHandler } from "./middleware/error.js";
4
+ import { router } from "./routes/index.js";
5
+
6
+ /**
7
+ * Simple router matcher for Bun native server
8
+ */
9
+ function match_route(pathname: string, method: string): Response | null {
10
+ return router(pathname, method);
11
+ }
12
+
13
+ const server = Bun.serve({
14
+ port: config.port,
15
+ async fetch(req) {
16
+ const url = new URL(req.url);
17
+ const start = Date.now();
18
+
19
+ try {
20
+ // Health check
21
+ if (url.pathname === "/health" && req.method === "GET") {
22
+ const response = Response.json({
23
+ status: "ok",
24
+ timestamp: new Date().toISOString(),
25
+ });
26
+ logger(req, response, Date.now() - start);
27
+ return response;
28
+ }
29
+
30
+ // Match routes
31
+ const response = match_route(url.pathname, req.method);
32
+ if (response) {
33
+ logger(req, response, Date.now() - start);
34
+ return response;
35
+ }
36
+
37
+ // 404 Not Found
38
+ const notFoundResponse = Response.json(
39
+ { error: "Not Found" },
40
+ { status: 404 }
41
+ );
42
+ logger(req, notFoundResponse, Date.now() - start);
43
+ return notFoundResponse;
44
+ } catch (error) {
45
+ return errorHandler(error, req);
46
+ }
47
+ },
48
+ });
49
+
50
+ console.log(`🚀 Server running on http://localhost:${server.port}`);
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Error handler for Bun native server
3
+ */
4
+ export function errorHandler(error: unknown, req: Request): Response {
5
+ console.error(`Error: ${error instanceof Error ? error.message : "Unknown error"}`, error);
6
+
7
+ const status = error instanceof Error && "status" in error
8
+ ? (error as Error & { status: number }).status
9
+ : 500;
10
+
11
+ const message = error instanceof Error ? error.message : "Internal Server Error";
12
+
13
+ return Response.json(
14
+ {
15
+ error: message,
16
+ status,
17
+ },
18
+ { status }
19
+ );
20
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Simple logger middleware for Bun native server
3
+ */
4
+ export function logger(req: Request, res: Response, duration: number): void {
5
+ console.log(`${req.method} ${new URL(req.url).pathname} - ${res.status} (${duration}ms)`);
6
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Simple router for Bun native server
3
+ * Add your routes here
4
+ */
5
+ export function router(pathname: string, method: string): Response | null {
6
+ // GET /
7
+ if (pathname === "/" && method === "GET") {
8
+ return Response.json({
9
+ message: "Welcome to your Bun backend!",
10
+ docs: "/docs",
11
+ });
12
+ }
13
+
14
+ // Add more routes here
15
+ // Example:
16
+ // if (pathname === "/users" && method === "GET") {
17
+ // return Response.json({ users: [] });
18
+ // }
19
+
20
+ return null; // No route matched
21
+ }
@@ -0,0 +1,2 @@
1
+ // Add your TypeScript types and interfaces here
2
+ export {};
@@ -0,0 +1,5 @@
1
+ import { config as dotenvConfig } from "dotenv";
2
+
3
+ export function load_env(): void {
4
+ dotenvConfig();
5
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ESNext"],
7
+ "types": ["bun-types"],
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+ "outDir": "./dist",
16
+ "rootDir": "./src"
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }
@@ -0,0 +1,3 @@
1
+ # Server Configuration
2
+ PORT=3000
3
+ NODE_ENV=development
@@ -0,0 +1,31 @@
1
+ # My Backend App
2
+
3
+ Production-ready Bun backend with TypeScript and Hono.
4
+
5
+ ## Getting Started
6
+
7
+ ```bash
8
+ # Install dependencies
9
+ bun install
10
+
11
+ # Copy environment variables
12
+ cp .env.example .env
13
+
14
+ # Run development server
15
+ bun run dev
16
+
17
+ # Build for production
18
+ bun run build
19
+
20
+ # Run production server
21
+ bun run start
22
+ ```
23
+
24
+ ## API Endpoints
25
+
26
+ - `GET /` - Welcome message
27
+ - `GET /health` - Health check
28
+
29
+ ## Documentation
30
+
31
+ Visit `/docs` for API documentation (if Swagger/Scalar is installed).
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "my-backend-app",
3
+ "version": "1.0.0",
4
+ "description": "Production-ready backend with Express and TypeScript",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "bun --watch src/index.ts",
8
+ "start": "bun src/index.ts",
9
+ "build": "bun build src/index.ts --outdir dist --target bun",
10
+ "type-check": "tsc --noEmit"
11
+ },
12
+ "dependencies": {
13
+ "express": "^4.18.2",
14
+ "dotenv": "^16.3.1"
15
+ },
16
+ "devDependencies": {
17
+ "@types/bun": "latest",
18
+ "@types/express": "^4.17.21",
19
+ "typescript": "^5.3.3"
20
+ }
21
+ }
@@ -0,0 +1,8 @@
1
+ import { load_env } from "../utils/env.js";
2
+
3
+ load_env();
4
+
5
+ export const config = {
6
+ port: parseInt(process.env.PORT || "3000", 10),
7
+ nodeEnv: process.env.NODE_ENV || "development",
8
+ } as const;
@@ -0,0 +1,27 @@
1
+ import express from "express";
2
+ import { logger as loggerMiddleware } from "./middleware/logger.js";
3
+ import { errorHandler } from "./middleware/error.js";
4
+ import routes from "./routes/index.js";
5
+ import { config } from "./config/index.js";
6
+
7
+ const app = express();
8
+
9
+ // Middleware
10
+ app.use(express.json());
11
+ app.use(express.urlencoded({ extended: true }));
12
+ app.use(loggerMiddleware);
13
+
14
+ // Routes
15
+ app.use("/", routes);
16
+
17
+ // Health check
18
+ app.get("/health", (req, res) => {
19
+ res.json({ status: "ok", timestamp: new Date().toISOString() });
20
+ });
21
+
22
+ // Error handler (must be last)
23
+ app.use(errorHandler);
24
+
25
+ app.listen(config.port, () => {
26
+ console.log(`🚀 Server running on http://localhost:${config.port}`);
27
+ });
@@ -0,0 +1,15 @@
1
+ import type { Request, Response, NextFunction } from "express";
2
+
3
+ export const errorHandler = (
4
+ err: Error & { status?: number },
5
+ req: Request,
6
+ res: Response,
7
+ next: NextFunction
8
+ ) => {
9
+ console.error(`Error: ${err.message}`, err);
10
+
11
+ res.status(err.status || 500).json({
12
+ error: err.message || "Internal Server Error",
13
+ status: err.status || 500,
14
+ });
15
+ };
@@ -0,0 +1,12 @@
1
+ import type { Request, Response, NextFunction } from "express";
2
+
3
+ export const logger = (req: Request, res: Response, next: NextFunction) => {
4
+ const start = Date.now();
5
+
6
+ res.on("finish", () => {
7
+ const ms = Date.now() - start;
8
+ console.log(`${req.method} ${req.url} - ${res.statusCode} (${ms}ms)`);
9
+ });
10
+
11
+ next();
12
+ };
@@ -0,0 +1,12 @@
1
+ import express from "express";
2
+
3
+ const router = express.Router();
4
+
5
+ router.get("/", (req, res) => {
6
+ res.json({
7
+ message: "Welcome to your Bun backend!",
8
+ docs: "/docs",
9
+ });
10
+ });
11
+
12
+ export default router;
@@ -0,0 +1,2 @@
1
+ // Add your TypeScript types and interfaces here
2
+ export {};
@@ -0,0 +1,5 @@
1
+ import { config as dotenvConfig } from "dotenv";
2
+
3
+ export function load_env(): void {
4
+ dotenvConfig();
5
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ESNext",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ESNext"],
7
+ "types": ["bun-types"],
8
+ "strict": true,
9
+ "esModuleInterop": true,
10
+ "skipLibCheck": true,
11
+ "forceConsistentCasingInFileNames": true,
12
+ "resolveJsonModule": true,
13
+ "isolatedModules": true,
14
+ "noEmit": true,
15
+ "outDir": "./dist",
16
+ "rootDir": "./src"
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }
@@ -0,0 +1 @@
1
+ export { validate, get_validated, type ValidateTarget } from "./validate.js";
@@ -0,0 +1,83 @@
1
+ import { Context, Next } from "hono";
2
+ import * as yup from "yup";
3
+
4
+ /**
5
+ * Validation middleware for Hono using Yup schemas
6
+ * Validates request body, query parameters, or route params
7
+ */
8
+
9
+ export type ValidateTarget = "body" | "query" | "param";
10
+
11
+ interface ValidationOptions {
12
+ target: ValidateTarget;
13
+ schema: yup.AnySchema;
14
+ }
15
+
16
+ /**
17
+ * Create a validation middleware
18
+ * @param options - Validation configuration
19
+ * @returns Hono middleware function
20
+ */
21
+ export function validate(options: ValidationOptions) {
22
+ return async (c: Context, next: Next) => {
23
+ try {
24
+ let data: unknown;
25
+
26
+ switch (options.target) {
27
+ case "body":
28
+ data = await c.req.json();
29
+ break;
30
+ case "query":
31
+ data = c.req.query();
32
+ break;
33
+ case "param":
34
+ data = c.req.param();
35
+ break;
36
+ default:
37
+ return c.json(
38
+ { error: "Invalid validation target" },
39
+ 400
40
+ );
41
+ }
42
+
43
+ // Validate data against schema
44
+ const validated = await options.schema.validate(data, {
45
+ abortEarly: false,
46
+ stripUnknown: true,
47
+ });
48
+
49
+ // Store validated data in context for route handlers
50
+ c.set(`validated_${options.target}`, validated);
51
+
52
+ await next();
53
+ } catch (error) {
54
+ if (error instanceof yup.ValidationError) {
55
+ return c.json(
56
+ {
57
+ error: "Validation failed",
58
+ details: error.inner.map((err) => ({
59
+ path: err.path || "unknown",
60
+ message: err.message,
61
+ })),
62
+ },
63
+ 400
64
+ );
65
+ }
66
+
67
+ return c.json(
68
+ { error: "Invalid request data" },
69
+ 400
70
+ );
71
+ }
72
+ };
73
+ }
74
+
75
+ /**
76
+ * Helper to get validated data from context
77
+ * @param c - Hono context
78
+ * @param target - Validation target (body/query/param)
79
+ * @returns Validated data
80
+ */
81
+ export function get_validated<T>(c: Context, target: ValidateTarget): T {
82
+ return c.get(`validated_${target}`) as T;
83
+ }
@@ -0,0 +1,132 @@
1
+ import { Hono } from "hono";
2
+ import * as yup from "yup";
3
+ import { validate, get_validated } from "../middleware/validate.js";
4
+
5
+ const users = new Hono();
6
+
7
+ /**
8
+ * Yup Schemas for validation
9
+ */
10
+
11
+ // Schema for creating a new user
12
+ const create_user_schema = yup.object({
13
+ name: yup.string().required().min(2, "Name must be at least 2 characters"),
14
+ email: yup.string().required().email("Invalid email format"),
15
+ age: yup.number().integer().min(18, "Must be at least 18 years old").optional(),
16
+ });
17
+
18
+ // Schema for updating a user
19
+ const update_user_schema = yup.object({
20
+ name: yup.string().min(2).optional(),
21
+ email: yup.string().email().optional(),
22
+ age: yup.number().integer().min(18).optional(),
23
+ });
24
+
25
+ // Schema for query parameters
26
+ const list_users_query_schema = yup.object({
27
+ page: yup.number().transform((value, originalValue) => {
28
+ return originalValue ? parseInt(originalValue, 10) : undefined;
29
+ }).optional(),
30
+ limit: yup.number().transform((value, originalValue) => {
31
+ return originalValue ? parseInt(originalValue, 10) : undefined;
32
+ }).optional(),
33
+ search: yup.string().optional(),
34
+ });
35
+
36
+ // Schema for route params
37
+ const user_id_param_schema = yup.object({
38
+ id: yup.string().required().uuid("Invalid user ID format"),
39
+ });
40
+
41
+ /**
42
+ * Routes with validation
43
+ */
44
+
45
+ // GET /users - List users with query validation
46
+ users.get(
47
+ "/",
48
+ validate({ target: "query", schema: list_users_query_schema }),
49
+ (c) => {
50
+ const query = get_validated<yup.InferType<typeof list_users_query_schema>>(c, "query");
51
+
52
+ return c.json({
53
+ users: [],
54
+ pagination: {
55
+ page: query.page || 1,
56
+ limit: query.limit || 10,
57
+ search: query.search,
58
+ },
59
+ });
60
+ }
61
+ );
62
+
63
+ // POST /users - Create user with body validation
64
+ users.post(
65
+ "/",
66
+ validate({ target: "body", schema: create_user_schema }),
67
+ (c) => {
68
+ const body = get_validated<yup.InferType<typeof create_user_schema>>(c, "body");
69
+
70
+ // Your database logic here
71
+ const new_user = {
72
+ id: crypto.randomUUID(),
73
+ ...body,
74
+ created_at: new Date().toISOString(),
75
+ };
76
+
77
+ return c.json(new_user, 201);
78
+ }
79
+ );
80
+
81
+ // GET /users/:id - Get user by ID with param validation
82
+ users.get(
83
+ "/:id",
84
+ validate({ target: "param", schema: user_id_param_schema }),
85
+ (c) => {
86
+ const params = get_validated<yup.InferType<typeof user_id_param_schema>>(c, "param");
87
+
88
+ // Your database logic here
89
+ const user = {
90
+ id: params.id,
91
+ name: "John Doe",
92
+ email: "john@example.com",
93
+ };
94
+
95
+ return c.json(user);
96
+ }
97
+ );
98
+
99
+ // PATCH /users/:id - Update user with param + body validation
100
+ users.patch(
101
+ "/:id",
102
+ validate({ target: "param", schema: user_id_param_schema }),
103
+ validate({ target: "body", schema: update_user_schema }),
104
+ (c) => {
105
+ const params = get_validated<yup.InferType<typeof user_id_param_schema>>(c, "param");
106
+ const body = get_validated<yup.InferType<typeof update_user_schema>>(c, "body");
107
+
108
+ // Your database logic here
109
+ const updated_user = {
110
+ id: params.id,
111
+ ...body,
112
+ updated_at: new Date().toISOString(),
113
+ };
114
+
115
+ return c.json(updated_user);
116
+ }
117
+ );
118
+
119
+ // DELETE /users/:id
120
+ users.delete(
121
+ "/:id",
122
+ validate({ target: "param", schema: user_id_param_schema }),
123
+ (c) => {
124
+ const params = get_validated<yup.InferType<typeof user_id_param_schema>>(c, "param");
125
+
126
+ return c.json({
127
+ message: `User ${params.id} deleted successfully`,
128
+ });
129
+ }
130
+ );
131
+
132
+ export default users;
@@ -0,0 +1 @@
1
+ export { validate, get_validated, type ValidateTarget } from "./validate.js";