create-turbo-mono 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 (54) hide show
  1. package/.claude/settings.local.json +14 -0
  2. package/README.md +182 -0
  3. package/dist/index.d.ts +3 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +118 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/scaffold.d.ts +8 -0
  8. package/dist/scaffold.d.ts.map +1 -0
  9. package/dist/scaffold.js +42 -0
  10. package/dist/scaffold.js.map +1 -0
  11. package/dist/templates/backend.d.ts +2 -0
  12. package/dist/templates/backend.d.ts.map +1 -0
  13. package/dist/templates/backend.js +424 -0
  14. package/dist/templates/backend.js.map +1 -0
  15. package/dist/templates/cicd.d.ts +3 -0
  16. package/dist/templates/cicd.d.ts.map +1 -0
  17. package/dist/templates/cicd.js +307 -0
  18. package/dist/templates/cicd.js.map +1 -0
  19. package/dist/templates/docker.d.ts +3 -0
  20. package/dist/templates/docker.d.ts.map +1 -0
  21. package/dist/templates/docker.js +458 -0
  22. package/dist/templates/docker.js.map +1 -0
  23. package/dist/templates/docs.d.ts +3 -0
  24. package/dist/templates/docs.d.ts.map +1 -0
  25. package/dist/templates/docs.js +71 -0
  26. package/dist/templates/docs.js.map +1 -0
  27. package/dist/templates/frontend.d.ts +2 -0
  28. package/dist/templates/frontend.d.ts.map +1 -0
  29. package/dist/templates/frontend.js +441 -0
  30. package/dist/templates/frontend.js.map +1 -0
  31. package/dist/templates/root.d.ts +3 -0
  32. package/dist/templates/root.d.ts.map +1 -0
  33. package/dist/templates/root.js +210 -0
  34. package/dist/templates/root.js.map +1 -0
  35. package/dist/templates/shared.d.ts +2 -0
  36. package/dist/templates/shared.d.ts.map +1 -0
  37. package/dist/templates/shared.js +696 -0
  38. package/dist/templates/shared.js.map +1 -0
  39. package/dist/utils.d.ts +5 -0
  40. package/dist/utils.d.ts.map +1 -0
  41. package/dist/utils.js +34 -0
  42. package/dist/utils.js.map +1 -0
  43. package/package.json +40 -0
  44. package/src/index.ts +138 -0
  45. package/src/scaffold.ts +51 -0
  46. package/src/templates/backend.ts +460 -0
  47. package/src/templates/cicd.ts +334 -0
  48. package/src/templates/docker.ts +503 -0
  49. package/src/templates/docs.ts +74 -0
  50. package/src/templates/frontend.ts +469 -0
  51. package/src/templates/root.ts +216 -0
  52. package/src/templates/shared.ts +820 -0
  53. package/src/utils.ts +31 -0
  54. package/tsconfig.json +20 -0
@@ -0,0 +1,307 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createCICDFiles = createCICDFiles;
7
+ const fs_extra_1 = __importDefault(require("fs-extra"));
8
+ const path_1 = __importDefault(require("path"));
9
+ async function createCICDFiles(config) {
10
+ const { targetDir, backends, frontends } = config;
11
+ await fs_extra_1.default.ensureDir(path_1.default.join(targetDir, '.github', 'workflows'));
12
+ await fs_extra_1.default.ensureDir(path_1.default.join(targetDir, 'scripts'));
13
+ await createGitHubWorkflow(targetDir, backends, frontends);
14
+ await createDeployScript(targetDir, backends, frontends);
15
+ await createRollbackScript(targetDir, backends, frontends);
16
+ await createEnvExample(targetDir);
17
+ }
18
+ async function createGitHubWorkflow(targetDir, backends, frontends) {
19
+ const services = [...backends, ...frontends];
20
+ const matrixServices = services.map((s) => `'${s}'`).join(', ');
21
+ // Using template literals with escaped ${ for GitHub Actions syntax
22
+ const workflow = `name: CI/CD (main)
23
+
24
+ on:
25
+ push:
26
+ branches: ['main']
27
+ pull_request:
28
+ branches: ['main']
29
+
30
+ env:
31
+ REGISTRY: ghcr.io
32
+ IMAGE_NAME: \${{ github.repository }}
33
+
34
+ jobs:
35
+ build-and-push:
36
+ runs-on: ubuntu-latest
37
+ permissions:
38
+ contents: read
39
+ packages: write
40
+ strategy:
41
+ fail-fast: false
42
+ matrix:
43
+ service: [${matrixServices}]
44
+
45
+ steps:
46
+ - name: ๐Ÿ“ฅ Checkout repository
47
+ uses: actions/checkout@v4
48
+
49
+ - name: ๐Ÿณ Set up QEMU
50
+ uses: docker/setup-qemu-action@v3
51
+
52
+ - name: ๐Ÿ—๏ธ Set up Docker Buildx
53
+ uses: docker/setup-buildx-action@v3
54
+
55
+ - name: ๐Ÿ” Login to GitHub Container Registry
56
+ uses: docker/login-action@v3
57
+ with:
58
+ registry: \${{ env.REGISTRY }}
59
+ username: \${{ github.actor }}
60
+ password: \${{ secrets.GITHUB_TOKEN }}
61
+
62
+ - name: ๐Ÿท๏ธ Extract metadata
63
+ id: meta
64
+ uses: docker/metadata-action@v5
65
+ with:
66
+ images: \${{ env.REGISTRY }}/\${{ env.IMAGE_NAME }}/\${{ matrix.service }}
67
+ tags: |
68
+ type=ref,event=branch
69
+ type=ref,event=pr
70
+ type=sha,prefix={{branch}}-
71
+ type=raw,value=latest,enable={{is_default_branch}}
72
+
73
+ - name: ๐Ÿ”จ Build and push Docker image
74
+ uses: docker/build-push-action@v5
75
+ with:
76
+ context: .
77
+ file: Dockerfile
78
+ target: \${{ matrix.service }}-production
79
+ push: \${{ github.event_name != 'pull_request' }}
80
+ tags: \${{ steps.meta.outputs.tags }}
81
+ labels: \${{ steps.meta.outputs.labels }}
82
+ cache-from: type=gha
83
+ cache-to: type=gha,mode=max
84
+
85
+ deploy:
86
+ needs: [build-and-push]
87
+ runs-on: ubuntu-latest
88
+ if: github.ref == 'refs/heads/main' && github.event_name == 'push'
89
+
90
+ steps:
91
+ - name: ๐Ÿ“ฅ Checkout repository
92
+ uses: actions/checkout@v4
93
+
94
+ - name: ๐Ÿท๏ธ Compute deployment tag
95
+ id: tag
96
+ run: echo "TAG=\${GITHUB_SHA::7}" >> $GITHUB_OUTPUT
97
+
98
+ - name: ๐Ÿš€ Deploy to server
99
+ uses: appleboy/ssh-action@v1.0.0
100
+ env:
101
+ TAG: \${{ steps.tag.outputs.TAG }}
102
+ APP_DIR: \${{ secrets.DEPLOY_PATH }}
103
+ with:
104
+ host: \${{ secrets.SSH_HOST }}
105
+ username: \${{ secrets.SSH_USER }}
106
+ key: \${{ secrets.SSH_KEY }}
107
+ port: \${{ secrets.SSH_PORT || 22 }}
108
+ script_stop: true
109
+ envs: TAG,APP_DIR
110
+ script: |
111
+ set -euo pipefail
112
+ echo "๐Ÿ“ฆ Deploying tag: \${TAG}"
113
+ echo "๐Ÿ“ APP_DIR: \${APP_DIR}"
114
+ cd "\${APP_DIR}"
115
+ chmod +x scripts/deploy.sh
116
+ ./scripts/deploy.sh "\${TAG}"
117
+
118
+ - name: โœ‰๏ธ Send deployment notification
119
+ if: always()
120
+ uses: dawidd6/action-send-mail@v3
121
+ with:
122
+ server_address: \${{ secrets.SMTP_SERVER }}
123
+ server_port: \${{ secrets.SMTP_PORT }}
124
+ secure: \${{ secrets.SMTP_SECURE }}
125
+ username: \${{ secrets.SMTP_USERNAME }}
126
+ password: \${{ secrets.SMTP_PASSWORD }}
127
+ subject: 'Deployment #\${{ github.run_number }} - \${{ job.status }}'
128
+ from: 'CI/CD <\${{ secrets.SMTP_USERNAME }}>'
129
+ to: \${{ secrets.DEPLOY_NOTIFY_TO }}
130
+ html_body: |
131
+ <div style="font-family:'Segoe UI',Helvetica,Arial,sans-serif;background:#f6f8fa;padding:20px;">
132
+ <div style="max-width:600px;margin:0 auto;background:#fff;border-radius:10px;box-shadow:0 2px 6px rgba(0,0,0,0.1);overflow:hidden;">
133
+ <div style="background:linear-gradient(90deg,#2563eb,#1e3a8a);padding:16px 24px;color:#fff;">
134
+ <h2 style="margin:0;font-size:20px;">๐Ÿš€ Deployment Notification</h2>
135
+ </div>
136
+ <div style="padding:24px;">
137
+ <table style="width:100%;border-collapse:collapse;margin-top:8px;">
138
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Repository</td><td>\${{ github.repository }}</td></tr>
139
+ <tr style="background:#f9fafb;"><td style="padding:6px 0;color:#555;font-weight:600;">Branch</td><td>\${{ github.ref_name }}</td></tr>
140
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Commit</td><td><code>\${{ github.sha }}</code></td></tr>
141
+ <tr style="background:#f9fafb;"><td style="padding:6px 0;color:#555;font-weight:600;">Tag</td><td>\${{ steps.tag.outputs.TAG }}</td></tr>
142
+ <tr><td style="padding:6px 0;color:#555;font-weight:600;">Status</td>
143
+ <td><span style="padding:3px 8px;border-radius:6px;background:#2563eb;color:#fff;font-size:12px;">\${{ job.status }}</span></td></tr>
144
+ </table>
145
+ <p style="margin:16px 0 8px;color:#444;">View full deployment logs:</p>
146
+ <a href="\${{ github.server_url }}/\${{ github.repository }}/actions/runs/\${{ github.run_id }}"
147
+ style="display:inline-block;background:#2563eb;color:#fff;padding:10px 16px;border-radius:6px;text-decoration:none;font-weight:500;">๐Ÿ” View Details</a>
148
+ <p style="margin-top:20px;font-size:12px;color:#888;">โ€” DevOps Pipeline</p>
149
+ </div>
150
+ </div>
151
+ </div>
152
+ `;
153
+ await fs_extra_1.default.writeFile(path_1.default.join(targetDir, '.github', 'workflows', 'ci-cd.yml'), workflow);
154
+ }
155
+ async function createDeployScript(targetDir, backends, frontends) {
156
+ const services = [...backends, ...frontends].join(' ');
157
+ const deployScript = `#!/usr/bin/env bash
158
+ set -euo pipefail
159
+
160
+ APP_DIR="\${APP_DIR:-/home/$(whoami)/app}"
161
+ COMPOSE_FILE="docker-compose.prod.yml"
162
+ PROJECT_NAME="\${PROJECT_NAME:-app}"
163
+
164
+ TAG="\${1:-}"
165
+ if [[ -z "\${TAG}" ]]; then
166
+ echo "โŒ Usage: ./scripts/deploy.sh <tag>"
167
+ exit 1
168
+ fi
169
+
170
+ echo "๐Ÿš€ Deploying tag \${TAG} in \${APP_DIR}"
171
+ cd "\${APP_DIR}"
172
+
173
+ export RELEASE_TAG="\${TAG}"
174
+
175
+ # Keep a pointer to the previous tag for rollback
176
+ if [[ -f .current_release_tag ]]; then
177
+ cp .current_release_tag .prev_release_tag
178
+ fi
179
+ echo "\${TAG}" > .current_release_tag
180
+
181
+ # 1) Pull latest images
182
+ echo "๐Ÿ“ฅ Pulling images for tag \${TAG}..."
183
+ docker compose -f "\${COMPOSE_FILE}" pull ${services}
184
+
185
+ # 2) Run database migrations
186
+ echo "๐Ÿงฉ Running database migrations..."
187
+ FIRST_BACKEND="${backends[0]}"
188
+ if ! docker compose -f "\${COMPOSE_FILE}" run --rm \${FIRST_BACKEND} sh -c 'pnpm prisma migrate deploy'; then
189
+ echo "โŒ Migration failed. Rolling back to previous tag..."
190
+ if [[ -f .prev_release_tag ]]; then
191
+ ./scripts/rollback.sh
192
+ fi
193
+ exit 1
194
+ fi
195
+
196
+ # 3) Start/Update services
197
+ echo "๐Ÿ”„ Starting containers..."
198
+ docker compose -f "\${COMPOSE_FILE}" up -d ${services}
199
+
200
+ # 4) Wait for services to be healthy
201
+ echo "๐Ÿ” Waiting for services to be healthy..."
202
+ for SERVICE in ${services}; do
203
+ CONTAINER_NAME="\${PROJECT_NAME}-\${SERVICE}"
204
+ for i in {1..30}; do
205
+ STATUS="$(docker inspect --format '{{json .State.Health.Status}}' "\${CONTAINER_NAME}" 2>/dev/null | tr -d '"')" || true
206
+ if [[ "\${STATUS}" == "healthy" ]] || [[ -z "\${STATUS}" ]]; then
207
+ echo "โœ… \${SERVICE} is healthy"
208
+ break
209
+ fi
210
+ if [[ \${i} -eq 30 ]]; then
211
+ echo "โš ๏ธ \${SERVICE} did not become healthy (timeout)"
212
+ fi
213
+ sleep 3
214
+ done
215
+ done
216
+
217
+ # 5) Cleanup old images
218
+ echo "๐Ÿงน Cleaning up old images..."
219
+ docker image prune -f
220
+
221
+ echo "โœ… Deployment successful for tag \${TAG}"
222
+ echo "๐Ÿ“Š Running services:"
223
+ docker compose -f "\${COMPOSE_FILE}" ps
224
+ `;
225
+ await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'scripts', 'deploy.sh'), deployScript, {
226
+ mode: 0o755,
227
+ });
228
+ }
229
+ async function createRollbackScript(targetDir, backends, frontends) {
230
+ const services = [...backends, ...frontends].join(' ');
231
+ const rollbackScript = `#!/usr/bin/env bash
232
+ set -euo pipefail
233
+
234
+ APP_DIR="\${APP_DIR:-/home/$(whoami)/app}"
235
+ COMPOSE_FILE="docker-compose.prod.yml"
236
+
237
+ cd "\${APP_DIR}"
238
+
239
+ if [[ ! -f .prev_release_tag ]]; then
240
+ echo "โŒ No .prev_release_tag found; cannot rollback."
241
+ exit 1
242
+ fi
243
+
244
+ export RELEASE_TAG="$(cat .prev_release_tag)"
245
+ echo "๐Ÿ”„ Rolling back to \${RELEASE_TAG}"
246
+
247
+ # Pull previous images
248
+ echo "๐Ÿ“ฅ Pulling images for tag \${RELEASE_TAG}..."
249
+ docker compose -f "\${COMPOSE_FILE}" pull ${services}
250
+
251
+ # Restart services
252
+ echo "๐Ÿ”„ Restarting services..."
253
+ docker compose -f "\${COMPOSE_FILE}" up -d ${services}
254
+
255
+ # Swap tag pointers
256
+ cp .prev_release_tag .current_release_tag
257
+
258
+ echo "โœ… Rolled back to \${RELEASE_TAG}"
259
+ echo "๐Ÿ“Š Running services:"
260
+ docker compose -f "\${COMPOSE_FILE}" ps
261
+ `;
262
+ await fs_extra_1.default.writeFile(path_1.default.join(targetDir, 'scripts', 'rollback.sh'), rollbackScript, { mode: 0o755 });
263
+ }
264
+ async function createEnvExample(targetDir) {
265
+ const envExample = `# Project Configuration
266
+ PROJECT_NAME=my-app
267
+ GITHUB_REPOSITORY=your-org/your-repo
268
+
269
+ # Database Configuration
270
+ DATABASE_USER=postgres
271
+ DATABASE_PASSWORD=postgres
272
+ DATABASE_NAME=app_db
273
+ DATABASE_PORT=5432
274
+ DATABASE_URL=postgresql://\${DATABASE_USER}:\${DATABASE_PASSWORD}@postgres:5432/\${DATABASE_NAME}
275
+
276
+ # Redis Configuration
277
+ REDIS_URL=redis://redis:6379
278
+ REDIS_PORT=6379
279
+
280
+ # Application Ports
281
+ # Backend services will use 4000+
282
+ # Frontend services will use 3000+
283
+
284
+ # Production Deployment
285
+ RELEASE_TAG=latest
286
+
287
+ # API Configuration
288
+ NEXT_PUBLIC_API_URL=http://localhost:4000
289
+
290
+ # Email Notifications (for CI/CD)
291
+ # SMTP_SERVER=smtp.gmail.com
292
+ # SMTP_PORT=587
293
+ # SMTP_SECURE=true
294
+ # SMTP_USERNAME=your-email@gmail.com
295
+ # SMTP_PASSWORD=your-app-password
296
+ # DEPLOY_NOTIFY_TO=team@example.com
297
+
298
+ # Deployment Server (for CI/CD)
299
+ # SSH_HOST=your-server.com
300
+ # SSH_USER=deploy
301
+ # SSH_KEY=<your-private-key>
302
+ # SSH_PORT=22
303
+ # DEPLOY_PATH=/home/deploy/app
304
+ `;
305
+ await fs_extra_1.default.writeFile(path_1.default.join(targetDir, '.env.example'), envExample);
306
+ }
307
+ //# sourceMappingURL=cicd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cicd.js","sourceRoot":"","sources":["../../src/templates/cicd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { ProjectConfig } from '../scaffold';
2
+ export declare function createDockerFiles(config: ProjectConfig): Promise<void>;
3
+ //# sourceMappingURL=docker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docker.d.ts","sourceRoot":"","sources":["../../src/templates/docker.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE5C,wBAAsB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5E"}