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.
- package/LICENSE +21 -0
- package/README.md +436 -0
- package/package.json +78 -0
- package/src/core/TechDetector.js +351 -0
- package/src/generators/ProjectGenerator.js +1241 -0
- package/src/generators/ProjectGeneratorExtensions.js +14 -0
- package/src/generators/TemplateMethods.js +402 -0
- package/src/generators/index.js +5 -0
- package/src/index.js +152 -0
- package/src/main.js +8 -0
- package/src/templates/common/README.md.hbs +358 -0
- package/src/templates/docker/index.js +518 -0
- package/src/templates/docker.js +58 -0
- package/src/templates/go/basic/api/routes/user.go.hbs +138 -0
- package/src/templates/go/basic/config/config.go.hbs +54 -0
- package/src/templates/go/basic/go.mod.hbs +8 -0
- package/src/templates/go/basic/main.go.hbs +70 -0
- package/src/templates/go/basic/models/user.go.hbs +69 -0
- package/src/templates/go/basic/services/user_service.go.hbs +173 -0
- package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/controller/UserController.java.hbs +91 -0
- package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/dto/ApiResponse.java.hbs +40 -0
- package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/model/User.java.hbs +102 -0
- package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/repository/UserRepository.java.hbs +20 -0
- package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/service/UserService.java.hbs +65 -0
- package/src/templates/java/basic/src/main/java/com/{{snakeCase projectName}}/{{projectName}}/{{pascalCase projectName}}Application.java.hbs +16 -0
- package/src/templates/node/basic/src/config/database.ts.hbs +18 -0
- package/src/templates/node/basic/src/controllers/UserController.ts.hbs +98 -0
- package/src/templates/node/basic/src/index.ts.hbs +45 -0
- package/src/templates/node/basic/src/middleware/errorHandler.ts.hbs +33 -0
- package/src/templates/node/basic/src/routes/index.ts.hbs +42 -0
- package/src/templates/node/basic/src/types/index.ts.hbs +18 -0
- package/src/templates/python/basic/config/database.py.hbs +36 -0
- package/src/templates/python/basic/main.py.hbs +58 -0
- package/src/templates/python/basic/middleware/error_handler.py.hbs +41 -0
- package/src/templates/python/basic/models/user.py.hbs +40 -0
- package/src/templates/python/basic/routes/__init__.py.hbs +12 -0
- package/src/templates/python/basic/routes/users.py.hbs +64 -0
- package/src/templates/rust/basic/Cargo.toml.hbs +39 -0
- package/src/templates/rust/basic/src/config/database.rs.hbs +27 -0
- package/src/templates/rust/basic/src/handlers/user.rs.hbs +130 -0
- package/src/templates/rust/basic/src/handlers/user_routes.rs.hbs +15 -0
- package/src/templates/rust/basic/src/main.rs.hbs +53 -0
- package/src/templates/rust/basic/src/models/mod.rs.hbs +79 -0
- package/src/templates/rust/basic/src/schema.rs.hbs +10 -0
- package/src/utils/FileManager.js +186 -0
- package/src/utils/Templates.js +231 -0
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
// Docker template generation methods
|
|
2
|
+
const generateDockerTemplates = {
|
|
3
|
+
node: function(config) {
|
|
4
|
+
return `# Stage 1: Build
|
|
5
|
+
FROM node:18-alpine AS builder
|
|
6
|
+
|
|
7
|
+
WORKDIR /app
|
|
8
|
+
|
|
9
|
+
# Copy package files
|
|
10
|
+
COPY package*.json ./
|
|
11
|
+
|
|
12
|
+
# Install dependencies
|
|
13
|
+
RUN npm ci --only=production
|
|
14
|
+
|
|
15
|
+
# Copy source code
|
|
16
|
+
COPY . .
|
|
17
|
+
|
|
18
|
+
# Build the application
|
|
19
|
+
${config.framework === 'typescript' || config.framework === 'nestjs' ? 'RUN npm run build' : ''}
|
|
20
|
+
|
|
21
|
+
# Stage 2: Production
|
|
22
|
+
FROM node:18-alpine AS production
|
|
23
|
+
|
|
24
|
+
WORKDIR /app
|
|
25
|
+
|
|
26
|
+
# Copy built application and dependencies
|
|
27
|
+
${config.framework === 'typescript' || config.framework === 'nestjs' ? 'COPY --from=builder /app/dist ./dist' : 'COPY --from=builder /app/src ./src'}
|
|
28
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
29
|
+
COPY --from=builder /app/package*.json ./
|
|
30
|
+
|
|
31
|
+
# Create non-root user
|
|
32
|
+
RUN addgroup -g 1001 -S nodejs
|
|
33
|
+
RUN adduser -S nextjs -u 1001
|
|
34
|
+
|
|
35
|
+
USER nextjs
|
|
36
|
+
|
|
37
|
+
EXPOSE 3000
|
|
38
|
+
|
|
39
|
+
ENV NODE_ENV=production
|
|
40
|
+
ENV PORT=3000
|
|
41
|
+
|
|
42
|
+
CMD ["npm", "start"]`;
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
python: function(config) {
|
|
46
|
+
return `FROM python:3.11-slim
|
|
47
|
+
|
|
48
|
+
WORKDIR /app
|
|
49
|
+
|
|
50
|
+
# Install system dependencies
|
|
51
|
+
RUN apt-get update && apt-get install -y \\
|
|
52
|
+
gcc \\
|
|
53
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
54
|
+
|
|
55
|
+
# Copy requirements and install Python dependencies
|
|
56
|
+
COPY requirements.txt .
|
|
57
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
58
|
+
|
|
59
|
+
# Copy application code
|
|
60
|
+
COPY . .
|
|
61
|
+
|
|
62
|
+
# Create non-root user
|
|
63
|
+
RUN useradd --create-home --shell /bin/bash app \\
|
|
64
|
+
&& chown -R app:app /app
|
|
65
|
+
USER app
|
|
66
|
+
|
|
67
|
+
EXPOSE 8000
|
|
68
|
+
|
|
69
|
+
ENV PYTHONPATH=/app
|
|
70
|
+
ENV PYTHONUNBUFFERED=1
|
|
71
|
+
|
|
72
|
+
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]`;
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
java: function(config) {
|
|
76
|
+
return `FROM maven:3.9-openjdk-17 AS builder
|
|
77
|
+
|
|
78
|
+
WORKDIR /app
|
|
79
|
+
|
|
80
|
+
# Copy pom.xml and download dependencies
|
|
81
|
+
COPY pom.xml .
|
|
82
|
+
RUN mvn dependency:go-offline
|
|
83
|
+
|
|
84
|
+
# Copy source code
|
|
85
|
+
COPY src ./src
|
|
86
|
+
|
|
87
|
+
# Build the application
|
|
88
|
+
RUN mvn clean package -DskipTests
|
|
89
|
+
|
|
90
|
+
# Production stage
|
|
91
|
+
FROM openjdk:17-jre-slim
|
|
92
|
+
|
|
93
|
+
WORKDIR /app
|
|
94
|
+
|
|
95
|
+
# Copy the built JAR file
|
|
96
|
+
COPY --from=builder /app/target/*.jar app.jar
|
|
97
|
+
|
|
98
|
+
# Create non-root user
|
|
99
|
+
RUN groupadd -r spring && useradd -r -g spring spring
|
|
100
|
+
USER spring
|
|
101
|
+
|
|
102
|
+
EXPOSE 8080
|
|
103
|
+
|
|
104
|
+
ENV JAVA_OPTS="-Xmx512m -Xms256m"
|
|
105
|
+
|
|
106
|
+
CMD ["java", "-jar", "app.jar"]`;
|
|
107
|
+
},
|
|
108
|
+
|
|
109
|
+
go: function(config) {
|
|
110
|
+
return `FROM golang:1.21-alpine AS builder
|
|
111
|
+
|
|
112
|
+
WORKDIR /app
|
|
113
|
+
|
|
114
|
+
# Copy go mod files
|
|
115
|
+
COPY go.mod go.sum ./
|
|
116
|
+
|
|
117
|
+
# Download dependencies
|
|
118
|
+
RUN go mod download
|
|
119
|
+
|
|
120
|
+
# Copy source code
|
|
121
|
+
COPY . .
|
|
122
|
+
|
|
123
|
+
# Build the application
|
|
124
|
+
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
|
|
125
|
+
|
|
126
|
+
# Production stage
|
|
127
|
+
FROM alpine:latest
|
|
128
|
+
|
|
129
|
+
RUN apk --no-cache add ca-certificates tzdata
|
|
130
|
+
|
|
131
|
+
WORKDIR /root/
|
|
132
|
+
|
|
133
|
+
# Copy the binary from builder stage
|
|
134
|
+
COPY --from=builder /app/main .
|
|
135
|
+
|
|
136
|
+
# Expose port
|
|
137
|
+
EXPOSE 8080
|
|
138
|
+
|
|
139
|
+
CMD ["./main"]`;
|
|
140
|
+
},
|
|
141
|
+
|
|
142
|
+
rust: function(config) {
|
|
143
|
+
return `FROM rust:1.70 as builder
|
|
144
|
+
|
|
145
|
+
WORKDIR /app
|
|
146
|
+
|
|
147
|
+
# Copy Cargo files
|
|
148
|
+
COPY Cargo.toml Cargo.lock ./
|
|
149
|
+
|
|
150
|
+
# Create dummy main.rs to cache dependencies
|
|
151
|
+
RUN mkdir src && echo "fn main() {}" > src/main.rs
|
|
152
|
+
RUN cargo build --release && rm -rf src
|
|
153
|
+
|
|
154
|
+
# Copy source code
|
|
155
|
+
COPY src ./src
|
|
156
|
+
|
|
157
|
+
# Build the application
|
|
158
|
+
RUN touch src/main.rs && cargo build --release
|
|
159
|
+
|
|
160
|
+
# Production stage
|
|
161
|
+
FROM debian:bookworm-slim
|
|
162
|
+
|
|
163
|
+
# Install runtime dependencies
|
|
164
|
+
RUN apt-get update && apt-get install -y \\
|
|
165
|
+
ca-certificates \\
|
|
166
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
167
|
+
|
|
168
|
+
WORKDIR /app
|
|
169
|
+
|
|
170
|
+
# Copy the binary from builder stage
|
|
171
|
+
COPY --from=builder /app/target/release/${config.projectName} .
|
|
172
|
+
|
|
173
|
+
# Create non-root user
|
|
174
|
+
RUN useradd -r -s /bin/false rustuser
|
|
175
|
+
USER rustuser
|
|
176
|
+
|
|
177
|
+
EXPOSE 8080
|
|
178
|
+
|
|
179
|
+
CMD ["./${config.projectName}"]`;
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
php: function(config) {
|
|
183
|
+
return `FROM php:8.2-fpm-alpine
|
|
184
|
+
|
|
185
|
+
# Install system dependencies
|
|
186
|
+
RUN apk add --no-cache \\
|
|
187
|
+
git \\
|
|
188
|
+
curl \\
|
|
189
|
+
libpng-dev \\
|
|
190
|
+
oniguruma-dev \\
|
|
191
|
+
libxml2-dev \\
|
|
192
|
+
zip \\
|
|
193
|
+
unzip \\
|
|
194
|
+
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
|
|
195
|
+
|
|
196
|
+
# Get latest Composer
|
|
197
|
+
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
|
198
|
+
|
|
199
|
+
# Set working directory
|
|
200
|
+
WORKDIR /var/www
|
|
201
|
+
|
|
202
|
+
# Copy application files
|
|
203
|
+
COPY . .
|
|
204
|
+
|
|
205
|
+
# Install PHP dependencies
|
|
206
|
+
RUN composer install --no-interaction --no-plugins --no-scripts --prefer-dist
|
|
207
|
+
|
|
208
|
+
# Set permissions
|
|
209
|
+
RUN chown -R www-data:www-data /var/www
|
|
210
|
+
RUN chmod -R 755 /var/www/storage
|
|
211
|
+
|
|
212
|
+
EXPOSE 9000
|
|
213
|
+
|
|
214
|
+
CMD ["php-fpm"]`;
|
|
215
|
+
}
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
// Docker Compose generation
|
|
219
|
+
function generateDockerCompose(config) {
|
|
220
|
+
const services = {
|
|
221
|
+
api: {
|
|
222
|
+
build: {
|
|
223
|
+
context: '.',
|
|
224
|
+
dockerfile: 'Dockerfile'
|
|
225
|
+
},
|
|
226
|
+
ports: ['3000:3000'],
|
|
227
|
+
environment: [
|
|
228
|
+
'NODE_ENV=production'
|
|
229
|
+
],
|
|
230
|
+
depends_on: config.database ? [config.database] : undefined,
|
|
231
|
+
restart: 'unless-stopped'
|
|
232
|
+
}
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
// Add database service if selected
|
|
236
|
+
if (config.database) {
|
|
237
|
+
const dbServices = {
|
|
238
|
+
mongodb: {
|
|
239
|
+
image: 'mongo:7.0',
|
|
240
|
+
ports: ['27017:27017'],
|
|
241
|
+
environment: [
|
|
242
|
+
'MONGO_INITDB_ROOT_USERNAME=admin',
|
|
243
|
+
'MONGO_INITDB_ROOT_PASSWORD=password',
|
|
244
|
+
`MONGO_INITDB_DATABASE=${config.projectName}`
|
|
245
|
+
],
|
|
246
|
+
volumes: ['mongodb_data:/data/db'],
|
|
247
|
+
restart: 'unless-stopped'
|
|
248
|
+
},
|
|
249
|
+
postgresql: {
|
|
250
|
+
image: 'postgres:15',
|
|
251
|
+
ports: ['5432:5432'],
|
|
252
|
+
environment: [
|
|
253
|
+
'POSTGRES_DB=postgres',
|
|
254
|
+
'POSTGRES_USER=postgres',
|
|
255
|
+
'POSTGRES_PASSWORD=password'
|
|
256
|
+
],
|
|
257
|
+
volumes: ['postgres_data:/var/lib/postgresql/data'],
|
|
258
|
+
restart: 'unless-stopped'
|
|
259
|
+
},
|
|
260
|
+
mysql: {
|
|
261
|
+
image: 'mysql:8.0',
|
|
262
|
+
ports: ['3306:3306'],
|
|
263
|
+
environment: [
|
|
264
|
+
`MYSQL_DATABASE=${config.projectName}`,
|
|
265
|
+
'MYSQL_ROOT_PASSWORD=password',
|
|
266
|
+
'MYSQL_USER=user',
|
|
267
|
+
'MYSQL_PASSWORD=password'
|
|
268
|
+
],
|
|
269
|
+
volumes: ['mysql_data:/var/lib/mysql'],
|
|
270
|
+
restart: 'unless-stopped'
|
|
271
|
+
},
|
|
272
|
+
redis: {
|
|
273
|
+
image: 'redis:7.0-alpine',
|
|
274
|
+
ports: ['6379:6379'],
|
|
275
|
+
volumes: ['redis_data:/data'],
|
|
276
|
+
restart: 'unless-stopped'
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
if (dbServices[config.database]) {
|
|
281
|
+
services[config.database] = dbServices[config.database];
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const dockerCompose = {
|
|
286
|
+
version: '3.8',
|
|
287
|
+
services,
|
|
288
|
+
volumes: {}
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// Add volume definitions
|
|
292
|
+
if (config.database && ['mongodb', 'postgresql', 'mysql', 'redis'].includes(config.database)) {
|
|
293
|
+
dockerCompose.volumes[`${config.database}_data`] = {};
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
return `version: '3.8'
|
|
297
|
+
|
|
298
|
+
services:
|
|
299
|
+
${Object.entries(services).map(([name, service]) => {
|
|
300
|
+
let serviceYaml = ` ${name}:\n`;
|
|
301
|
+
|
|
302
|
+
if (service.build) {
|
|
303
|
+
serviceYaml += ` build:\n`;
|
|
304
|
+
Object.entries(service.build).forEach(([key, value]) => {
|
|
305
|
+
serviceYaml += ` ${key}: ${typeof value === 'string' ? value : ''}\n`;
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
if (service.image) {
|
|
310
|
+
serviceYaml += ` image: ${service.image}\n`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
if (service.ports) {
|
|
314
|
+
serviceYaml += ` ports:\n`;
|
|
315
|
+
service.ports.forEach(port => {
|
|
316
|
+
serviceYaml += ` - "${port}"\n`;
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
if (service.environment) {
|
|
321
|
+
serviceYaml += ` environment:\n`;
|
|
322
|
+
service.environment.forEach(env => {
|
|
323
|
+
serviceYaml += ` - ${env}\n`;
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (service.depends_on) {
|
|
328
|
+
serviceYaml += ` depends_on:\n`;
|
|
329
|
+
service.depends_on.forEach(dep => {
|
|
330
|
+
serviceYaml += ` - ${dep}\n`;
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
if (service.volumes) {
|
|
335
|
+
serviceYaml += ` volumes:\n`;
|
|
336
|
+
service.volumes.forEach(vol => {
|
|
337
|
+
serviceYaml += ` - ${vol}\n`;
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (service.restart) {
|
|
342
|
+
serviceYaml += ` restart: ${service.restart}\n`;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return serviceYaml;
|
|
346
|
+
}).join('')}
|
|
347
|
+
${Object.keys(dockerCompose.volumes).length > 0 ? `
|
|
348
|
+
volumes:
|
|
349
|
+
${Object.keys(dockerCompose.volumes).map(vol => ` ${vol}:`).join('\n')}` : ''}`;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Dockerignore generation
|
|
353
|
+
function generateDockerignore(config) {
|
|
354
|
+
const commonIgnore = `
|
|
355
|
+
# Dependencies
|
|
356
|
+
node_modules/
|
|
357
|
+
__pycache__/
|
|
358
|
+
target/
|
|
359
|
+
build/
|
|
360
|
+
dist/
|
|
361
|
+
vendor/
|
|
362
|
+
|
|
363
|
+
# Environment variables
|
|
364
|
+
.env
|
|
365
|
+
.env.local
|
|
366
|
+
.env.*.local
|
|
367
|
+
|
|
368
|
+
# Logs
|
|
369
|
+
logs
|
|
370
|
+
*.log
|
|
371
|
+
npm-debug.log*
|
|
372
|
+
yarn-debug.log*
|
|
373
|
+
yarn-error.log*
|
|
374
|
+
|
|
375
|
+
# Runtime data
|
|
376
|
+
pids
|
|
377
|
+
*.pid
|
|
378
|
+
*.seed
|
|
379
|
+
*.pid.lock
|
|
380
|
+
|
|
381
|
+
# Coverage directory used by tools like istanbul
|
|
382
|
+
coverage/
|
|
383
|
+
*.lcov
|
|
384
|
+
|
|
385
|
+
# IDE files
|
|
386
|
+
.vscode/
|
|
387
|
+
.idea/
|
|
388
|
+
*.swp
|
|
389
|
+
*.swo
|
|
390
|
+
|
|
391
|
+
# OS files
|
|
392
|
+
.DS_Store
|
|
393
|
+
Thumbs.db
|
|
394
|
+
|
|
395
|
+
# Git
|
|
396
|
+
.git
|
|
397
|
+
.gitignore
|
|
398
|
+
|
|
399
|
+
# Documentation
|
|
400
|
+
README.md
|
|
401
|
+
docs/
|
|
402
|
+
|
|
403
|
+
# Test files
|
|
404
|
+
test/
|
|
405
|
+
tests/
|
|
406
|
+
*.test.js
|
|
407
|
+
*.spec.js
|
|
408
|
+
`;
|
|
409
|
+
|
|
410
|
+
return commonIgnore;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// CI/CD templates
|
|
414
|
+
function generateGitHubActions(config) {
|
|
415
|
+
return `name: CI/CD Pipeline
|
|
416
|
+
|
|
417
|
+
on:
|
|
418
|
+
push:
|
|
419
|
+
branches: [ main, develop ]
|
|
420
|
+
pull_request:
|
|
421
|
+
branches: [ main ]
|
|
422
|
+
|
|
423
|
+
jobs:
|
|
424
|
+
test:
|
|
425
|
+
runs-on: ubuntu-latest
|
|
426
|
+
|
|
427
|
+
services:
|
|
428
|
+
${config.database ? `${config.database}:
|
|
429
|
+
image: ${getDatabaseImage(config.database)}
|
|
430
|
+
ports:
|
|
431
|
+
- ${getDatabasePort(config.database)}:${getDatabasePort(config.database)}
|
|
432
|
+
env:
|
|
433
|
+
${getDatabaseEnv(config.database)}` : ''}
|
|
434
|
+
|
|
435
|
+
steps:
|
|
436
|
+
- uses: actions/checkout@v3
|
|
437
|
+
|
|
438
|
+
- name: Setup Node.js
|
|
439
|
+
uses: actions/setup-node@v3
|
|
440
|
+
with:
|
|
441
|
+
node-version: '18'
|
|
442
|
+
cache: 'npm'
|
|
443
|
+
|
|
444
|
+
- name: Install dependencies
|
|
445
|
+
run: npm ci
|
|
446
|
+
|
|
447
|
+
- name: Run tests
|
|
448
|
+
run: npm test
|
|
449
|
+
env:
|
|
450
|
+
${config.database ? getTestEnv(config) : ''}
|
|
451
|
+
|
|
452
|
+
- name: Build application
|
|
453
|
+
run: npm run build
|
|
454
|
+
|
|
455
|
+
deploy:
|
|
456
|
+
needs: test
|
|
457
|
+
runs-on: ubuntu-latest
|
|
458
|
+
if: github.ref == 'refs/heads/main'
|
|
459
|
+
|
|
460
|
+
steps:
|
|
461
|
+
- uses: actions/checkout@v3
|
|
462
|
+
|
|
463
|
+
- name: Deploy to production
|
|
464
|
+
run: |
|
|
465
|
+
echo "Deploy to production"
|
|
466
|
+
# Add your deployment commands here
|
|
467
|
+
`;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
function getDatabaseImage(database) {
|
|
471
|
+
const images = {
|
|
472
|
+
mongodb: 'mongo:7.0',
|
|
473
|
+
postgresql: 'postgres:15',
|
|
474
|
+
mysql: 'mysql:8.0',
|
|
475
|
+
redis: 'redis:7.0'
|
|
476
|
+
};
|
|
477
|
+
return images[database] || '';
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
function getDatabasePort(database) {
|
|
481
|
+
const ports = {
|
|
482
|
+
mongodb: '27017',
|
|
483
|
+
postgresql: '5432',
|
|
484
|
+
mysql: '3306',
|
|
485
|
+
redis: '6379'
|
|
486
|
+
};
|
|
487
|
+
return ports[database] || '';
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
function getDatabaseEnv(database) {
|
|
491
|
+
const envs = {
|
|
492
|
+
mongodb: 'MONGO_INITDB_ROOT_USERNAME: admin\n MONGO_INITDB_ROOT_PASSWORD: password',
|
|
493
|
+
postgresql: 'POSTGRES_PASSWORD: password\n POSTGRES_USER: postgres',
|
|
494
|
+
mysql: 'MYSQL_ROOT_PASSWORD: password\n MYSQL_DATABASE: test'
|
|
495
|
+
};
|
|
496
|
+
return envs[database] || '';
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
function getTestEnv(config) {
|
|
500
|
+
const envs = {
|
|
501
|
+
mongodb: `MONGODB_URI: mongodb://admin:password@localhost:${getDatabasePort(config.database)}/test`,
|
|
502
|
+
postgresql: `DATABASE_URL: postgresql://postgres:password@localhost:${getDatabasePort(config.database)}/test`,
|
|
503
|
+
mysql: `DATABASE_URL: mysql://root:password@localhost:${getDatabasePort(config.database)}/test`
|
|
504
|
+
};
|
|
505
|
+
return envs[config.database] || '';
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
module.exports = {
|
|
509
|
+
generateDockerfileNode: generateDockerTemplates.node,
|
|
510
|
+
generateDockerfilePython: generateDockerTemplates.python,
|
|
511
|
+
generateDockerfileJava: generateDockerTemplates.java,
|
|
512
|
+
generateDockerfileGo: generateDockerTemplates.go,
|
|
513
|
+
generateDockerfileRust: generateDockerTemplates.rust,
|
|
514
|
+
generateDockerfilePhp: generateDockerTemplates.php,
|
|
515
|
+
generateDockerCompose,
|
|
516
|
+
generateDockerignore,
|
|
517
|
+
generateGitHubActions
|
|
518
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module.exports = {
|
|
2
|
+
generateDockerfileNode(config) {
|
|
3
|
+
return `FROM node:18-alpine
|
|
4
|
+
|
|
5
|
+
WORKDIR /app
|
|
6
|
+
|
|
7
|
+
COPY package*.json ./
|
|
8
|
+
RUN npm ci --only=production
|
|
9
|
+
|
|
10
|
+
COPY . .
|
|
11
|
+
RUN npm run build
|
|
12
|
+
|
|
13
|
+
EXPOSE 3000
|
|
14
|
+
|
|
15
|
+
CMD ["npm", "start"]`;
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
generateDockerCompose(config) {
|
|
19
|
+
const dbServices = {
|
|
20
|
+
mongodb: `
|
|
21
|
+
mongodb:
|
|
22
|
+
image: mongo:7.0
|
|
23
|
+
ports:
|
|
24
|
+
- "27017:27017"
|
|
25
|
+
volumes:
|
|
26
|
+
- mongodb_data:/data/db`,
|
|
27
|
+
postgresql: `
|
|
28
|
+
postgres:
|
|
29
|
+
image: postgres:15
|
|
30
|
+
ports:
|
|
31
|
+
- "5432:5432"
|
|
32
|
+
environment:
|
|
33
|
+
POSTGRES_DB: ${config.projectName}
|
|
34
|
+
POSTGRES_USER: postgres
|
|
35
|
+
POSTGRES_PASSWORD: password
|
|
36
|
+
volumes:
|
|
37
|
+
- postgres_data:/var/lib/postgresql/data`
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const dbService = config.database ? dbServices[config.database] : '';
|
|
41
|
+
|
|
42
|
+
return `version: '3.8'
|
|
43
|
+
|
|
44
|
+
services:
|
|
45
|
+
api:
|
|
46
|
+
build: .
|
|
47
|
+
ports:
|
|
48
|
+
- "3000:3000"
|
|
49
|
+
depends_on:
|
|
50
|
+
${config.database ? ` - ${config.database}` : ''}
|
|
51
|
+
environment:
|
|
52
|
+
- DATABASE_URL=${config.database ? `${config.database}://localhost:27017/${config.projectName}` : ''}
|
|
53
|
+
${dbService}
|
|
54
|
+
|
|
55
|
+
volumes:
|
|
56
|
+
${config.database ? ` ${config.database}_data:` : ''}`;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
package routes
|
|
2
|
+
|
|
3
|
+
import (
|
|
4
|
+
"net/http"
|
|
5
|
+
"strconv"
|
|
6
|
+
|
|
7
|
+
"{{projectName}}/models"
|
|
8
|
+
"{{projectName}}/services"
|
|
9
|
+
|
|
10
|
+
"github.com/gin-gonic/gin"
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
func SetupRoutes(rg *gin.RouterGroup) {
|
|
14
|
+
userService := services.NewUserService()
|
|
15
|
+
|
|
16
|
+
users := rg.Group("/users")
|
|
17
|
+
{
|
|
18
|
+
users.GET("", GetUsers(userService))
|
|
19
|
+
users.GET("/:id", GetUser(userService))
|
|
20
|
+
users.POST("", CreateUser(userService))
|
|
21
|
+
users.PUT("/:id", UpdateUser(userService))
|
|
22
|
+
users.DELETE("/:id", DeleteUser(userService))
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func GetUsers(userService *services.UserService) gin.HandlerFunc {
|
|
27
|
+
return func(c *gin.Context) {
|
|
28
|
+
users, err := userService.GetAllUsers()
|
|
29
|
+
if err != nil {
|
|
30
|
+
c.JSON(http.StatusInternalServerError, gin.H{
|
|
31
|
+
"success": false,
|
|
32
|
+
"error": gin.H{"message": "Failed to fetch users"},
|
|
33
|
+
})
|
|
34
|
+
return
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
c.JSON(http.StatusOK, gin.H{
|
|
38
|
+
"success": true,
|
|
39
|
+
"data": users,
|
|
40
|
+
})
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
func GetUser(userService *services.UserService) gin.HandlerFunc {
|
|
45
|
+
return func(c *gin.Context) {
|
|
46
|
+
id := c.Param("id")
|
|
47
|
+
|
|
48
|
+
user, err := userService.GetUserByID(id)
|
|
49
|
+
if err != nil {
|
|
50
|
+
c.JSON(http.StatusNotFound, gin.H{
|
|
51
|
+
"success": false,
|
|
52
|
+
"error": gin.H{"message": "User not found"},
|
|
53
|
+
})
|
|
54
|
+
return
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
c.JSON(http.StatusOK, gin.H{
|
|
58
|
+
"success": true,
|
|
59
|
+
"data": user,
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
func CreateUser(userService *services.UserService) gin.HandlerFunc {
|
|
65
|
+
return func(c *gin.Context) {
|
|
66
|
+
var user models.User
|
|
67
|
+
if err := c.ShouldBindJSON(&user); err != nil {
|
|
68
|
+
c.JSON(http.StatusBadRequest, gin.H{
|
|
69
|
+
"success": false,
|
|
70
|
+
"error": gin.H{"message": "Invalid request body"},
|
|
71
|
+
})
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
createdUser, err := userService.CreateUser(&user)
|
|
76
|
+
if err != nil {
|
|
77
|
+
c.JSON(http.StatusInternalServerError, gin.H{
|
|
78
|
+
"success": false,
|
|
79
|
+
"error": gin.H{"message": "Failed to create user"},
|
|
80
|
+
})
|
|
81
|
+
return
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
c.JSON(http.StatusCreated, gin.H{
|
|
85
|
+
"success": true,
|
|
86
|
+
"data": createdUser,
|
|
87
|
+
})
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func UpdateUser(userService *services.UserService) gin.HandlerFunc {
|
|
92
|
+
return func(c *gin.Context) {
|
|
93
|
+
id := c.Param("id")
|
|
94
|
+
|
|
95
|
+
var user models.User
|
|
96
|
+
if err := c.ShouldBindJSON(&user); err != nil {
|
|
97
|
+
c.JSON(http.StatusBadRequest, gin.H{
|
|
98
|
+
"success": false,
|
|
99
|
+
"error": gin.H{"message": "Invalid request body"},
|
|
100
|
+
})
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
updatedUser, err := userService.UpdateUser(id, &user)
|
|
105
|
+
if err != nil {
|
|
106
|
+
c.JSON(http.StatusNotFound, gin.H{
|
|
107
|
+
"success": false,
|
|
108
|
+
"error": gin.H{"message": "User not found"},
|
|
109
|
+
})
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
c.JSON(http.StatusOK, gin.H{
|
|
114
|
+
"success": true,
|
|
115
|
+
"data": updatedUser,
|
|
116
|
+
})
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
func DeleteUser(userService *services.UserService) gin.HandlerFunc {
|
|
121
|
+
return func(c *gin.Context) {
|
|
122
|
+
id := c.Param("id")
|
|
123
|
+
|
|
124
|
+
err := userService.DeleteUser(id)
|
|
125
|
+
if err != nil {
|
|
126
|
+
c.JSON(http.StatusNotFound, gin.H{
|
|
127
|
+
"success": false,
|
|
128
|
+
"error": gin.H{"message": "User not found"},
|
|
129
|
+
})
|
|
130
|
+
return
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
c.JSON(http.StatusOK, gin.H{
|
|
134
|
+
"success": true,
|
|
135
|
+
"message": "User deleted successfully",
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
}
|