openwork-agent 1.0.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.
Files changed (46) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +436 -0
  3. package/package.json +78 -0
  4. package/src/core/TechDetector.js +351 -0
  5. package/src/generators/ProjectGenerator.js +1241 -0
  6. package/src/generators/ProjectGeneratorExtensions.js +14 -0
  7. package/src/generators/TemplateMethods.js +402 -0
  8. package/src/generators/index.js +5 -0
  9. package/src/index.js +152 -0
  10. package/src/main.js +8 -0
  11. package/src/templates/common/README.md.hbs +358 -0
  12. package/src/templates/docker/index.js +518 -0
  13. package/src/templates/docker.js +58 -0
  14. package/src/templates/go/basic/api/routes/user.go.hbs +138 -0
  15. package/src/templates/go/basic/config/config.go.hbs +54 -0
  16. package/src/templates/go/basic/go.mod.hbs +8 -0
  17. package/src/templates/go/basic/main.go.hbs +70 -0
  18. package/src/templates/go/basic/models/user.go.hbs +69 -0
  19. package/src/templates/go/basic/services/user_service.go.hbs +173 -0
  20. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/controller/UserController.java.hbs +91 -0
  21. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/dto/ApiResponse.java.hbs +40 -0
  22. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/model/User.java.hbs +102 -0
  23. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/repository/UserRepository.java.hbs +20 -0
  24. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/service/UserService.java.hbs +65 -0
  25. package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/{{pascalCase projectName}}Application.java.hbs +16 -0
  26. package/src/templates/node/basic/src/config/database.ts.hbs +18 -0
  27. package/src/templates/node/basic/src/controllers/UserController.ts.hbs +98 -0
  28. package/src/templates/node/basic/src/index.ts.hbs +45 -0
  29. package/src/templates/node/basic/src/middleware/errorHandler.ts.hbs +33 -0
  30. package/src/templates/node/basic/src/routes/index.ts.hbs +42 -0
  31. package/src/templates/node/basic/src/types/index.ts.hbs +18 -0
  32. package/src/templates/python/basic/config/database.py.hbs +36 -0
  33. package/src/templates/python/basic/main.py.hbs +58 -0
  34. package/src/templates/python/basic/middleware/error_handler.py.hbs +41 -0
  35. package/src/templates/python/basic/models/user.py.hbs +40 -0
  36. package/src/templates/python/basic/routes/__init__.py.hbs +12 -0
  37. package/src/templates/python/basic/routes/users.py.hbs +64 -0
  38. package/src/templates/rust/basic/Cargo.toml.hbs +39 -0
  39. package/src/templates/rust/basic/src/config/database.rs.hbs +27 -0
  40. package/src/templates/rust/basic/src/handlers/user.rs.hbs +130 -0
  41. package/src/templates/rust/basic/src/handlers/user_routes.rs.hbs +15 -0
  42. package/src/templates/rust/basic/src/main.rs.hbs +53 -0
  43. package/src/templates/rust/basic/src/models/mod.rs.hbs +79 -0
  44. package/src/templates/rust/basic/src/schema.rs.hbs +10 -0
  45. package/src/utils/FileManager.js +186 -0
  46. package/src/utils/Templates.js +231 -0
@@ -0,0 +1,16 @@
1
+ package com.{{snakeCase projectName}}.{{projectName}};
2
+
3
+ import org.springframework.boot.SpringApplication;
4
+ import org.springframework.boot.autoconfigure.SpringBootApplication;
5
+ import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
6
+
7
+ @SpringBootApplication
8
+ @EnableMongoRepositories
9
+ public class {{pascalCase projectName}}Application {
10
+
11
+ public static void main(String[] args) {
12
+ SpringApplication.run({{pascalCase projectName}}Application.class, args);
13
+ System.out.println("🚀 " + "{{pascalCase projectName}}" + " application started successfully!");
14
+ }
15
+
16
+ }
@@ -0,0 +1,18 @@
1
+ import mongoose from 'mongoose';
2
+
3
+ export async function connectDatabase(): Promise<void> {
4
+ const mongoUri = process.env.MONGODB_URI || 'mongodb://localhost:27017/{{projectName}}';
5
+
6
+ try {
7
+ await mongoose.connect(mongoUri);
8
+ console.log('✅ Connected to MongoDB');
9
+ } catch (error) {
10
+ console.error('❌ MongoDB connection error:', error);
11
+ throw error;
12
+ }
13
+ }
14
+
15
+ export const disconnectDatabase = (): void => {
16
+ mongoose.connection.close();
17
+ console.log('🔌 Disconnected from MongoDB');
18
+ };
@@ -0,0 +1,98 @@
1
+ import { Request, Response } from 'express';
2
+
3
+ export class UserController {
4
+ async getUsers(req: Request, res: Response) {
5
+ try {
6
+ // TODO: Implement user retrieval logic
7
+ const users = [];
8
+ res.json({
9
+ success: true,
10
+ data: users
11
+ });
12
+ } catch (error) {
13
+ res.status(500).json({
14
+ success: false,
15
+ message: 'Failed to fetch users'
16
+ });
17
+ }
18
+ }
19
+
20
+ async getUser(req: Request, res: Response) {
21
+ try {
22
+ const { id } = req.params;
23
+ // TODO: Implement user retrieval by ID
24
+ const user = null;
25
+
26
+ if (!user) {
27
+ return res.status(404).json({
28
+ success: false,
29
+ message: 'User not found'
30
+ });
31
+ }
32
+
33
+ res.json({
34
+ success: true,
35
+ data: user
36
+ });
37
+ } catch (error) {
38
+ res.status(500).json({
39
+ success: false,
40
+ message: 'Failed to fetch user'
41
+ });
42
+ }
43
+ }
44
+
45
+ async createUser(req: Request, res: Response) {
46
+ try {
47
+ const userData = req.body;
48
+ // TODO: Implement user creation logic
49
+ const newUser = { id: 1, ...userData };
50
+
51
+ res.status(201).json({
52
+ success: true,
53
+ data: newUser
54
+ });
55
+ } catch (error) {
56
+ res.status(500).json({
57
+ success: false,
58
+ message: 'Failed to create user'
59
+ });
60
+ }
61
+ }
62
+
63
+ async updateUser(req: Request, res: Response) {
64
+ try {
65
+ const { id } = req.params;
66
+ const userData = req.body;
67
+ // TODO: Implement user update logic
68
+ const updatedUser = { id, ...userData };
69
+
70
+ res.json({
71
+ success: true,
72
+ data: updatedUser
73
+ });
74
+ } catch (error) {
75
+ res.status(500).json({
76
+ success: false,
77
+ message: 'Failed to update user'
78
+ });
79
+ }
80
+ }
81
+
82
+ async deleteUser(req: Request, res: Response) {
83
+ try {
84
+ const { id } = req.params;
85
+ // TODO: Implement user deletion logic
86
+
87
+ res.json({
88
+ success: true,
89
+ message: 'User deleted successfully'
90
+ });
91
+ } catch (error) {
92
+ res.status(500).json({
93
+ success: false,
94
+ message: 'Failed to delete user'
95
+ });
96
+ }
97
+ }
98
+ }
@@ -0,0 +1,45 @@
1
+ import express from 'express';
2
+ import cors from 'cors';
3
+ import helmet from 'helmet';
4
+ import dotenv from 'dotenv';
5
+
6
+ import { connectDatabase } from './config/database';
7
+ import { errorHandler } from './middleware/errorHandler';
8
+ import routes from './routes';
9
+
10
+ dotenv.config();
11
+
12
+ const app = express();
13
+ const PORT = process.env.PORT || 3000;
14
+
15
+ // Middleware
16
+ app.use(helmet());
17
+ app.use(cors());
18
+ app.use(express.json());
19
+ app.use(express.urlencoded({ extended: true }));
20
+
21
+ // Routes
22
+ app.use('/api', routes);
23
+
24
+ // Health check
25
+ app.get('/health', (req, res) => {
26
+ res.json({ status: 'OK', timestamp: new Date().toISOString() });
27
+ });
28
+
29
+ // Error handling
30
+ app.use(errorHandler);
31
+
32
+ // Database connection and server start
33
+ async function startServer() {
34
+ try {
35
+ await connectDatabase();
36
+ app.listen(PORT, () => {
37
+ console.log(`🚀 Server running on port ${PORT}`);
38
+ });
39
+ } catch (error) {
40
+ console.error('Failed to start server:', error);
41
+ process.exit(1);
42
+ }
43
+ }
44
+
45
+ startServer();
@@ -0,0 +1,33 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+
3
+ export interface ApiError extends Error {
4
+ statusCode?: number;
5
+ isOperational?: boolean;
6
+ }
7
+
8
+ export const createError = (message: string, statusCode: number): ApiError => {
9
+ const error = new Error(message) as ApiError;
10
+ error.statusCode = statusCode;
11
+ error.isOperational = true;
12
+ return error;
13
+ };
14
+
15
+ export const errorHandler = (
16
+ error: ApiError,
17
+ req: Request,
18
+ res: Response,
19
+ next: NextFunction
20
+ ): void => {
21
+ const statusCode = error.statusCode || 500;
22
+ const message = error.message || 'Internal Server Error';
23
+
24
+ console.error('Error:', error);
25
+
26
+ res.status(statusCode).json({
27
+ success: false,
28
+ error: {
29
+ message,
30
+ ...(process.env.NODE_ENV === 'development' && { stack: error.stack })
31
+ }
32
+ });
33
+ };
@@ -0,0 +1,42 @@
1
+ import { Router } from 'express';
2
+ import { UserController } from '../controllers/UserController';
3
+
4
+ const router = Router();
5
+ const userController = new UserController();
6
+
7
+ /**
8
+ * @route GET /api/users
9
+ * @desc Get all users
10
+ * @access Public
11
+ */
12
+ router.get('/users', userController.getUsers);
13
+
14
+ /**
15
+ * @route GET /api/users/:id
16
+ * @desc Get user by ID
17
+ * @access Public
18
+ */
19
+ router.get('/users/:id', userController.getUser);
20
+
21
+ /**
22
+ * @route POST /api/users
23
+ * @desc Create a new user
24
+ * @access Public
25
+ */
26
+ router.post('/users', userController.createUser);
27
+
28
+ /**
29
+ * @route PUT /api/users/:id
30
+ * @desc Update user by ID
31
+ * @access Public
32
+ */
33
+ router.put('/users/:id', userController.updateUser);
34
+
35
+ /**
36
+ * @route DELETE /api/users/:id
37
+ * @desc Delete user by ID
38
+ * @access Public
39
+ */
40
+ router.delete('/users/:id', userController.deleteUser);
41
+
42
+ export default router;
@@ -0,0 +1,18 @@
1
+ export interface User {
2
+ _id?: string;
3
+ name: string;
4
+ email: string;
5
+ age?: number;
6
+ createdAt?: Date;
7
+ updatedAt?: Date;
8
+ }
9
+
10
+ export interface ApiResponse<T = any> {
11
+ success: boolean;
12
+ data?: T;
13
+ message?: string;
14
+ error?: {
15
+ message: string;
16
+ stack?: string;
17
+ };
18
+ }
@@ -0,0 +1,36 @@
1
+ from motor.motor_asyncio import AsyncIOMotorClient
2
+ from pymongo.errors import ConnectionFailure
3
+ import os
4
+ from typing import Optional
5
+
6
+ client: Optional[AsyncIOMotorClient] = None
7
+ database = None
8
+
9
+ async def connect_database():
10
+ """Connect to MongoDB database"""
11
+ global client, database
12
+
13
+ try:
14
+ mongo_uri = os.getenv("MONGODB_URI", "mongodb://localhost:27017/{{projectName}}")
15
+ client = AsyncIOMotorClient(mongo_uri)
16
+
17
+ # Test the connection
18
+ await client.admin.command('ping')
19
+
20
+ database = client[os.getenv("DB_NAME", "{{projectName}}")]
21
+ print("✅ Connected to MongoDB")
22
+
23
+ except ConnectionFailure as e:
24
+ print(f"❌ MongoDB connection error: {e}")
25
+ raise
26
+
27
+ async def disconnect_database():
28
+ """Disconnect from MongoDB"""
29
+ global client
30
+ if client:
31
+ client.close()
32
+ print("🔌 Disconnected from MongoDB")
33
+
34
+ async def get_database():
35
+ """Get database instance"""
36
+ return database
@@ -0,0 +1,58 @@
1
+ from fastapi import FastAPI, HTTPException
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from fastapi.responses import JSONResponse
4
+ import uvicorn
5
+ import os
6
+ from dotenv import load_dotenv
7
+
8
+ from config.database import connect_database
9
+ from routes import api_router
10
+ from middleware.error_handler import global_exception_handler
11
+
12
+ load_dotenv()
13
+
14
+ app = FastAPI(
15
+ title="{{pascalCase projectName}} API",
16
+ description="{{description}}",
17
+ version="1.0.0"
18
+ )
19
+
20
+ # CORS middleware
21
+ app.add_middleware(
22
+ CORSMiddleware,
23
+ allow_origins=["*"],
24
+ allow_credentials=True,
25
+ allow_methods=["*"],
26
+ allow_headers=["*"],
27
+ )
28
+
29
+ # Global exception handler
30
+ app.exception_handler(Exception)(global_exception_handler)
31
+
32
+ # Include routes
33
+ app.include_router(api_router, prefix="/api")
34
+
35
+ @app.get("/health")
36
+ async def health_check():
37
+ return {
38
+ "status": "OK",
39
+ "timestamp": "2024-01-01T00:00:00Z"
40
+ }
41
+
42
+ @app.on_event("startup")
43
+ async def startup_event():
44
+ await connect_database()
45
+ print("🚀 Server started successfully")
46
+
47
+ @app.on_event("shutdown")
48
+ async def shutdown_event():
49
+ print("🔌 Server shutting down")
50
+
51
+ if __name__ == "__main__":
52
+ port = int(os.getenv("PORT", 8000))
53
+ uvicorn.run(
54
+ "main:app",
55
+ host="0.0.0.0",
56
+ port=port,
57
+ reload=True
58
+ )
@@ -0,0 +1,41 @@
1
+ from fastapi import Request, HTTPException
2
+ from fastapi.responses import JSONResponse
3
+ import logging
4
+
5
+ logger = logging.getLogger(__name__)
6
+
7
+ async def global_exception_handler(request: Request, exc: Exception):
8
+ """Global exception handler for FastAPI"""
9
+
10
+ logger.error(f"Unhandled exception: {str(exc)}")
11
+
12
+ return JSONResponse(
13
+ status_code=500,
14
+ content={
15
+ "success": False,
16
+ "error": {
17
+ "message": "Internal server error",
18
+ "type": type(exc).__name__
19
+ }
20
+ }
21
+ )
22
+
23
+ class APIException(Exception):
24
+ """Custom API exception"""
25
+ def __init__(self, message: str, status_code: int = 400):
26
+ self.message = message
27
+ self.status_code = status_code
28
+ super().__init__(self.message)
29
+
30
+ async def api_exception_handler(request: Request, exc: APIException):
31
+ """Handler for custom API exceptions"""
32
+
33
+ return JSONResponse(
34
+ status_code=exc.status_code,
35
+ content={
36
+ "success": False,
37
+ "error": {
38
+ "message": exc.message
39
+ }
40
+ }
41
+ )
@@ -0,0 +1,40 @@
1
+ from pydantic import BaseModel, EmailStr
2
+ from typing import Optional
3
+ from datetime import datetime
4
+ from bson import ObjectId
5
+
6
+ class PyObjectId(ObjectId):
7
+ """Custom ObjectId class for Pydantic"""
8
+ @classmethod
9
+ def __get_validators__(cls):
10
+ yield cls.validate
11
+
12
+ @classmethod
13
+ def validate(cls, v):
14
+ if not ObjectId.is_valid(v):
15
+ raise ValueError("Invalid objectid")
16
+ return ObjectId(v)
17
+
18
+ class UserBase(BaseModel):
19
+ name: str
20
+ email: EmailStr
21
+ age: Optional[int] = None
22
+
23
+ class UserCreate(UserBase):
24
+ pass
25
+
26
+ class UserUpdate(BaseModel):
27
+ name: Optional[str] = None
28
+ email: Optional[EmailStr] = None
29
+ age: Optional[int] = None
30
+
31
+ class User(UserBase):
32
+ id: Optional[PyObjectId] = None
33
+ created_at: Optional[datetime] = None
34
+ updated_at: Optional[datetime] = None
35
+
36
+ class Config:
37
+ arbitrary_types_allowed = True
38
+ json_encoders = {
39
+ ObjectId: str
40
+ }
@@ -0,0 +1,12 @@
1
+ from fastapi import APIRouter
2
+ from routes import users
3
+
4
+ api_router = APIRouter()
5
+
6
+ api_router.include_router(users.router)
7
+
8
+ @app.get("/")
9
+ async def root():
10
+ return {"message": "{{pascalCase projectName}} API is running"}
11
+
12
+ __all__ = ["api_router"]
@@ -0,0 +1,64 @@
1
+ from fastapi import APIRouter, HTTPException, Depends
2
+ from typing import List, Optional
3
+ from models.user import User, UserCreate, UserUpdate
4
+ from services.user_service import UserService
5
+
6
+ router = APIRouter()
7
+ user_service = UserService()
8
+
9
+ @router.get("/users", response_model=List[User])
10
+ async def get_users():
11
+ """Get all users"""
12
+ try:
13
+ users = await user_service.get_all_users()
14
+ return users
15
+ except Exception as e:
16
+ raise HTTPException(status_code=500, detail="Failed to fetch users")
17
+
18
+ @router.get("/users/{user_id}", response_model=User)
19
+ async def get_user(user_id: str):
20
+ """Get user by ID"""
21
+ try:
22
+ user = await user_service.get_user_by_id(user_id)
23
+ if not user:
24
+ raise HTTPException(status_code=404, detail="User not found")
25
+ return user
26
+ except HTTPException:
27
+ raise
28
+ except Exception as e:
29
+ raise HTTPException(status_code=500, detail="Failed to fetch user")
30
+
31
+ @router.post("/users", response_model=User, status_code=201)
32
+ async def create_user(user_data: UserCreate):
33
+ """Create a new user"""
34
+ try:
35
+ user = await user_service.create_user(user_data)
36
+ return user
37
+ except Exception as e:
38
+ raise HTTPException(status_code=500, detail="Failed to create user")
39
+
40
+ @router.put("/users/{user_id}", response_model=User)
41
+ async def update_user(user_id: str, user_data: UserUpdate):
42
+ """Update user by ID"""
43
+ try:
44
+ user = await user_service.update_user(user_id, user_data)
45
+ if not user:
46
+ raise HTTPException(status_code=404, detail="User not found")
47
+ return user
48
+ except HTTPException:
49
+ raise
50
+ except Exception as e:
51
+ raise HTTPException(status_code=500, detail="Failed to update user")
52
+
53
+ @router.delete("/users/{user_id}")
54
+ async def delete_user(user_id: str):
55
+ """Delete user by ID"""
56
+ try:
57
+ success = await user_service.delete_user(user_id)
58
+ if not success:
59
+ raise HTTPException(status_code=404, detail="User not found")
60
+ return {"success": True, "message": "User deleted successfully"}
61
+ except HTTPException:
62
+ raise
63
+ except Exception as e:
64
+ raise HTTPException(status_code=500, detail="Failed to delete user")
@@ -0,0 +1,39 @@
1
+ [package]
2
+ name = "{{projectName}}"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ authors = ["{{author}}"]
6
+ description = "{{description}}"
7
+
8
+ [dependencies]
9
+ # Web framework
10
+ actix-web = "4.4"
11
+ actix-cors = "0.7"
12
+
13
+ # Database
14
+ diesel = { version = "2.1", features = ["postgres", "uuid", "chrono", "r2d2"] }
15
+ diesel_migrations = "2.1"
16
+
17
+ # Serialization
18
+ serde = { version = "1.0", features = ["derive"] }
19
+ serde_json = "1.0"
20
+
21
+ # UUID
22
+ uuid = { version = "1.5", features = ["v4", "serde"] }
23
+
24
+ # Date/Time
25
+ chrono = { version = "0.4", features = ["serde"] }
26
+
27
+ # Environment
28
+ dotenv = "0.15"
29
+
30
+ # Logging
31
+ log = "0.4"
32
+ env_logger = "0.10"
33
+
34
+ # Async
35
+ tokio = { version = "1.32", features = ["full"] }
36
+
37
+ # Error handling
38
+ anyhow = "1.0"
39
+ thiserror = "1.0"
@@ -0,0 +1,27 @@
1
+ use diesel::prelude::*;
2
+ use diesel::r2d2::{self, ConnectionManager};
3
+ use std::env;
4
+
5
+ pub type DbPool = r2d2::Pool<ConnectionManager<PgConnection>>;
6
+
7
+ pub fn establish_connection() -> DbPool {
8
+ dotenv::dotenv().ok();
9
+
10
+ let database_url = env::var("DATABASE_URL")
11
+ .expect("DATABASE_URL must be set");
12
+
13
+ let manager = ConnectionManager::<PgConnection>::new(database_url);
14
+ r2d2::Pool::builder()
15
+ .build(manager)
16
+ .expect("Failed to create pool.")
17
+ }
18
+
19
+ pub fn run_migrations(pool: &DbPool) {
20
+ use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness};
21
+
22
+ const MIGRATIONS: EmbeddedMigrations = embed_migrations!();
23
+
24
+ let mut conn = pool.get().expect("Failed to get connection");
25
+ conn.run_pending_migrations(MIGRATIONS)
26
+ .expect("Failed to run migrations");
27
+ }