@expressots/cli 3.0.0 → 4.0.0-preview.2

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 (180) hide show
  1. package/README.md +41 -95
  2. package/bin/cicd/cli.d.ts +6 -0
  3. package/bin/cicd/cli.js +126 -0
  4. package/bin/cicd/form.d.ts +29 -0
  5. package/bin/cicd/form.js +345 -0
  6. package/bin/cicd/generators/azure-devops.d.ts +2 -0
  7. package/bin/cicd/generators/azure-devops.js +370 -0
  8. package/bin/cicd/generators/bitbucket.d.ts +2 -0
  9. package/bin/cicd/generators/bitbucket.js +217 -0
  10. package/bin/cicd/generators/circleci.d.ts +2 -0
  11. package/bin/cicd/generators/circleci.js +274 -0
  12. package/bin/cicd/generators/github-actions.d.ts +14 -0
  13. package/bin/cicd/generators/github-actions.js +426 -0
  14. package/bin/cicd/generators/gitlab-ci.d.ts +2 -0
  15. package/bin/cicd/generators/gitlab-ci.js +237 -0
  16. package/bin/cicd/generators/index.d.ts +6 -0
  17. package/bin/cicd/generators/index.js +15 -0
  18. package/bin/cicd/generators/jenkins.d.ts +2 -0
  19. package/bin/cicd/generators/jenkins.js +248 -0
  20. package/bin/cicd/generators/template-loader.d.ts +17 -0
  21. package/bin/cicd/generators/template-loader.js +128 -0
  22. package/bin/cicd/index.d.ts +1 -0
  23. package/bin/cicd/index.js +5 -0
  24. package/bin/cli.d.ts +1 -1
  25. package/bin/cli.js +18 -3
  26. package/bin/commands/project.commands.d.ts +19 -6
  27. package/bin/commands/project.commands.js +390 -61
  28. package/bin/config/index.d.ts +5 -0
  29. package/bin/config/index.js +10 -0
  30. package/bin/config/manager.d.ts +98 -0
  31. package/bin/config/manager.js +222 -0
  32. package/bin/containerize/analyzers/bootstrap-analyzer.d.ts +46 -0
  33. package/bin/containerize/analyzers/bootstrap-analyzer.js +187 -0
  34. package/bin/containerize/analyzers/project-analyzer.d.ts +20 -0
  35. package/bin/containerize/analyzers/project-analyzer.js +150 -0
  36. package/bin/containerize/cli.d.ts +4 -0
  37. package/bin/containerize/cli.js +113 -0
  38. package/bin/containerize/form.d.ts +15 -0
  39. package/bin/containerize/form.js +154 -0
  40. package/bin/containerize/generators/ci-generator.d.ts +31 -0
  41. package/bin/containerize/generators/ci-generator.js +936 -0
  42. package/bin/containerize/generators/docker-compose-generator.d.ts +8 -0
  43. package/bin/containerize/generators/docker-compose-generator.js +186 -0
  44. package/bin/containerize/generators/dockerfile-generator.d.ts +8 -0
  45. package/bin/containerize/generators/dockerfile-generator.js +635 -0
  46. package/bin/containerize/generators/kubernetes-generator.d.ts +8 -0
  47. package/bin/containerize/generators/kubernetes-generator.js +133 -0
  48. package/bin/containerize/generators/template-loader.d.ts +36 -0
  49. package/bin/containerize/generators/template-loader.js +129 -0
  50. package/bin/containerize/index.d.ts +4 -0
  51. package/bin/containerize/index.js +13 -0
  52. package/bin/containerize/presets/preset-registry.d.ts +20 -0
  53. package/bin/containerize/presets/preset-registry.js +102 -0
  54. package/bin/costs/cli.d.ts +5 -0
  55. package/bin/costs/cli.js +183 -0
  56. package/bin/costs/form.d.ts +44 -0
  57. package/bin/costs/form.js +412 -0
  58. package/bin/costs/index.d.ts +4 -0
  59. package/bin/costs/index.js +25 -0
  60. package/bin/costs/pricing-manager.d.ts +84 -0
  61. package/bin/costs/pricing-manager.js +342 -0
  62. package/bin/costs/providers/index.d.ts +32 -0
  63. package/bin/costs/providers/index.js +153 -0
  64. package/bin/costs/sources/api-source.d.ts +10 -0
  65. package/bin/costs/sources/api-source.js +32 -0
  66. package/bin/costs/sources/index.d.ts +6 -0
  67. package/bin/costs/sources/index.js +15 -0
  68. package/bin/costs/sources/local-json-source.d.ts +23 -0
  69. package/bin/costs/sources/local-json-source.js +59 -0
  70. package/bin/costs/sources/remote-json-source.d.ts +11 -0
  71. package/bin/costs/sources/remote-json-source.js +53 -0
  72. package/bin/costs/types.d.ts +53 -0
  73. package/bin/costs/types.js +5 -0
  74. package/bin/dev/cli.d.ts +4 -0
  75. package/bin/dev/cli.js +134 -0
  76. package/bin/dev/form.d.ts +36 -0
  77. package/bin/dev/form.js +254 -0
  78. package/bin/dev/index.d.ts +1 -0
  79. package/bin/dev/index.js +5 -0
  80. package/bin/generate/cli.js +29 -2
  81. package/bin/generate/form.d.ts +5 -1
  82. package/bin/generate/form.js +3 -3
  83. package/bin/generate/templates/nonopinionated/config.tpl +12 -0
  84. package/bin/generate/templates/nonopinionated/event.tpl +10 -0
  85. package/bin/generate/templates/nonopinionated/guard.tpl +18 -0
  86. package/bin/generate/templates/nonopinionated/handler.tpl +12 -0
  87. package/bin/generate/templates/nonopinionated/interceptor.tpl +27 -0
  88. package/bin/generate/templates/opinionated/config.tpl +47 -0
  89. package/bin/generate/templates/opinionated/entity.tpl +1 -8
  90. package/bin/generate/templates/opinionated/event.tpl +15 -0
  91. package/bin/generate/templates/opinionated/guard.tpl +41 -0
  92. package/bin/generate/templates/opinionated/handler.tpl +23 -0
  93. package/bin/generate/templates/opinionated/interceptor.tpl +50 -0
  94. package/bin/generate/utils/command-utils.d.ts +7 -3
  95. package/bin/generate/utils/command-utils.js +95 -31
  96. package/bin/generate/utils/nonopininated-cmd.d.ts +10 -1
  97. package/bin/generate/utils/nonopininated-cmd.js +100 -1
  98. package/bin/generate/utils/opinionated-cmd.d.ts +10 -1
  99. package/bin/generate/utils/opinionated-cmd.js +112 -7
  100. package/bin/generate/utils/string-utils.d.ts +6 -0
  101. package/bin/generate/utils/string-utils.js +13 -1
  102. package/bin/help/form.js +11 -3
  103. package/bin/migrate/analyzers/platform-detector.d.ts +14 -0
  104. package/bin/migrate/analyzers/platform-detector.js +116 -0
  105. package/bin/migrate/cli.d.ts +6 -0
  106. package/bin/migrate/cli.js +96 -0
  107. package/bin/migrate/form.d.ts +25 -0
  108. package/bin/migrate/form.js +347 -0
  109. package/bin/migrate/generators/compose-to-k8s.d.ts +2 -0
  110. package/bin/migrate/generators/compose-to-k8s.js +324 -0
  111. package/bin/migrate/generators/compose-to-railway.d.ts +2 -0
  112. package/bin/migrate/generators/compose-to-railway.js +138 -0
  113. package/bin/migrate/generators/compose-to-render.d.ts +2 -0
  114. package/bin/migrate/generators/compose-to-render.js +148 -0
  115. package/bin/migrate/generators/generic-migration.d.ts +9 -0
  116. package/bin/migrate/generators/generic-migration.js +221 -0
  117. package/bin/migrate/generators/heroku-to-fly.d.ts +2 -0
  118. package/bin/migrate/generators/heroku-to-fly.js +291 -0
  119. package/bin/migrate/generators/heroku-to-railway.d.ts +2 -0
  120. package/bin/migrate/generators/heroku-to-railway.js +283 -0
  121. package/bin/migrate/generators/heroku-to-render.d.ts +2 -0
  122. package/bin/migrate/generators/heroku-to-render.js +148 -0
  123. package/bin/migrate/generators/index.d.ts +7 -0
  124. package/bin/migrate/generators/index.js +17 -0
  125. package/bin/migrate/generators/template-loader.d.ts +21 -0
  126. package/bin/migrate/generators/template-loader.js +59 -0
  127. package/bin/migrate/index.d.ts +1 -0
  128. package/bin/migrate/index.js +5 -0
  129. package/bin/new/cli.js +21 -6
  130. package/bin/new/form.d.ts +25 -4
  131. package/bin/new/form.js +285 -70
  132. package/bin/profile/analyzers/dockerfile-analyzer.d.ts +27 -0
  133. package/bin/profile/analyzers/dockerfile-analyzer.js +122 -0
  134. package/bin/profile/analyzers/image-analyzer.d.ts +19 -0
  135. package/bin/profile/analyzers/image-analyzer.js +85 -0
  136. package/bin/profile/cli.d.ts +4 -0
  137. package/bin/profile/cli.js +92 -0
  138. package/bin/profile/form.d.ts +56 -0
  139. package/bin/profile/form.js +400 -0
  140. package/bin/profile/index.d.ts +1 -0
  141. package/bin/profile/index.js +5 -0
  142. package/bin/profile/optimizers/index.d.ts +19 -0
  143. package/bin/profile/optimizers/index.js +137 -0
  144. package/bin/providers/add/form.d.ts +1 -1
  145. package/bin/providers/add/form.js +27 -6
  146. package/bin/providers/create/form.js +2 -1
  147. package/bin/scripts/form.js +27 -5
  148. package/bin/studio/cli.d.ts +15 -0
  149. package/bin/studio/cli.js +166 -0
  150. package/bin/studio/index.d.ts +5 -0
  151. package/bin/studio/index.js +9 -0
  152. package/bin/templates/cache.d.ts +54 -0
  153. package/bin/templates/cache.js +180 -0
  154. package/bin/templates/cli.d.ts +8 -0
  155. package/bin/templates/cli.js +292 -0
  156. package/bin/templates/fetcher.d.ts +49 -0
  157. package/bin/templates/fetcher.js +208 -0
  158. package/bin/templates/index.d.ts +11 -0
  159. package/bin/templates/index.js +37 -0
  160. package/bin/templates/manager.d.ts +116 -0
  161. package/bin/templates/manager.js +323 -0
  162. package/bin/templates/renderer.d.ts +49 -0
  163. package/bin/templates/renderer.js +204 -0
  164. package/bin/templates/types.d.ts +51 -0
  165. package/bin/templates/types.js +5 -0
  166. package/bin/utils/add-module-to-container.d.ts +2 -2
  167. package/bin/utils/add-module-to-container.js +15 -5
  168. package/bin/utils/cli-ui.d.ts +30 -3
  169. package/bin/utils/cli-ui.js +95 -13
  170. package/bin/utils/index.d.ts +4 -0
  171. package/bin/utils/index.js +4 -0
  172. package/bin/utils/input-validation.d.ts +50 -0
  173. package/bin/utils/input-validation.js +143 -0
  174. package/bin/utils/package-manager-commands.d.ts +24 -0
  175. package/bin/utils/package-manager-commands.js +50 -0
  176. package/bin/utils/safe-spawn.d.ts +35 -0
  177. package/bin/utils/safe-spawn.js +51 -0
  178. package/bin/utils/update-tsconfig-paths.d.ts +35 -0
  179. package/bin/utils/update-tsconfig-paths.js +286 -0
  180. package/package.json +154 -154
@@ -0,0 +1,370 @@
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.generateAzureDevOps = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const template_loader_1 = require("./template-loader");
11
+ async function generateAzureDevOps(outputDir, options) {
12
+ // Try remote template, fall back to embedded
13
+ const result = await (0, template_loader_1.loadCICDTemplate)("azure", options.strategy, options, generateAzureContentEmbedded);
14
+ (0, template_loader_1.logTemplateSource)("Azure DevOps", result.source);
15
+ const filePath = path_1.default.join(outputDir, "azure-pipelines.yml");
16
+ fs_1.default.writeFileSync(filePath, result.content, "utf-8");
17
+ console.log(chalk_1.default.green(` ✓ Created azure-pipelines.yml`));
18
+ }
19
+ exports.generateAzureDevOps = generateAzureDevOps;
20
+ /**
21
+ * Embedded template generator (fallback when remote templates unavailable)
22
+ */
23
+ function generateAzureContentEmbedded(options) {
24
+ const { projectName, nodeVersion, packageManager, strategy, includeSecurity, includeE2E, includeCoverage, deployTarget, branch, port, } = options;
25
+ const installCmd = packageManager === "pnpm"
26
+ ? "pnpm install"
27
+ : packageManager === "yarn"
28
+ ? "yarn install"
29
+ : "npm ci";
30
+ const testCmd = packageManager === "pnpm"
31
+ ? "pnpm test"
32
+ : packageManager === "yarn"
33
+ ? "yarn test"
34
+ : "npm test";
35
+ const buildCmd = packageManager === "pnpm"
36
+ ? "pnpm build"
37
+ : packageManager === "yarn"
38
+ ? "yarn build"
39
+ : "npm run build";
40
+ const lintCmd = packageManager === "pnpm"
41
+ ? "pnpm lint"
42
+ : packageManager === "yarn"
43
+ ? "yarn lint"
44
+ : "npm run lint";
45
+ let content = `# Azure DevOps Pipeline
46
+ # Generated by ExpressoTS CLI
47
+ # Strategy: ${strategy}
48
+
49
+ trigger:
50
+ branches:
51
+ include:
52
+ - ${branch}
53
+ paths:
54
+ exclude:
55
+ - '*.md'
56
+ - 'docs/*'
57
+
58
+ pr:
59
+ branches:
60
+ include:
61
+ - ${branch}
62
+
63
+ variables:
64
+ nodeVersion: '${nodeVersion}'
65
+ dockerRegistry: '$(DOCKER_REGISTRY)'
66
+ imageName: '${projectName}'
67
+ containerPort: ${port}
68
+ vmImageName: 'ubuntu-latest'
69
+
70
+ stages:
71
+ - stage: Build
72
+ displayName: 'Build & Test'
73
+ jobs:
74
+ - job: Lint
75
+ displayName: 'Lint Code'
76
+ pool:
77
+ vmImage: $(vmImageName)
78
+ steps:
79
+ - task: NodeTool@0
80
+ displayName: 'Install Node.js'
81
+ inputs:
82
+ versionSpec: '$(nodeVersion)'
83
+
84
+ - task: Cache@2
85
+ displayName: 'Cache npm packages'
86
+ inputs:
87
+ key: 'npm | "$(Agent.OS)" | package-lock.json'
88
+ restoreKeys: |
89
+ npm | "$(Agent.OS)"
90
+ path: $(npm_config_cache)
91
+
92
+ - script: ${installCmd}
93
+ displayName: 'Install dependencies'
94
+
95
+ - script: ${lintCmd}
96
+ displayName: 'Run linter'
97
+
98
+ - job: Test
99
+ displayName: 'Run Tests'
100
+ dependsOn: Lint
101
+ pool:
102
+ vmImage: $(vmImageName)
103
+ steps:
104
+ - task: NodeTool@0
105
+ displayName: 'Install Node.js'
106
+ inputs:
107
+ versionSpec: '$(nodeVersion)'
108
+
109
+ - script: ${installCmd}
110
+ displayName: 'Install dependencies'
111
+
112
+ - script: ${testCmd}${includeCoverage ? " --coverage --coverageReporters=cobertura" : ""}
113
+ displayName: 'Run tests'
114
+ `;
115
+ if (includeCoverage) {
116
+ content += `
117
+ - task: PublishCodeCoverageResults@1
118
+ displayName: 'Publish code coverage'
119
+ inputs:
120
+ codeCoverageTool: 'Cobertura'
121
+ summaryFileLocation: '$(System.DefaultWorkingDirectory)/coverage/cobertura-coverage.xml'
122
+ reportDirectory: '$(System.DefaultWorkingDirectory)/coverage'
123
+ `;
124
+ }
125
+ // Security scanning
126
+ if (includeSecurity &&
127
+ (strategy === "comprehensive" || strategy === "security-focused")) {
128
+ content += `
129
+ - job: Security
130
+ displayName: 'Security Scanning'
131
+ dependsOn: Lint
132
+ pool:
133
+ vmImage: $(vmImageName)
134
+ steps:
135
+ - task: NodeTool@0
136
+ displayName: 'Install Node.js'
137
+ inputs:
138
+ versionSpec: '$(nodeVersion)'
139
+
140
+ - script: ${installCmd}
141
+ displayName: 'Install dependencies'
142
+
143
+ - script: npm audit --audit-level=high || true
144
+ displayName: 'npm audit'
145
+ `;
146
+ if (strategy === "security-focused") {
147
+ content += `
148
+ - task: SnykSecurityScan@1
149
+ displayName: 'Snyk Security Scan'
150
+ inputs:
151
+ serviceConnectionEndpoint: 'snyk-connection'
152
+ testType: 'app'
153
+ failOnIssues: false
154
+ continueOnError: true
155
+ `;
156
+ }
157
+ }
158
+ // E2E tests
159
+ if (includeE2E) {
160
+ content += `
161
+ - job: E2E
162
+ displayName: 'E2E Tests'
163
+ dependsOn: Test
164
+ pool:
165
+ vmImage: $(vmImageName)
166
+ steps:
167
+ - task: NodeTool@0
168
+ displayName: 'Install Node.js'
169
+ inputs:
170
+ versionSpec: '$(nodeVersion)'
171
+
172
+ - script: ${installCmd}
173
+ displayName: 'Install dependencies'
174
+
175
+ - script: ${buildCmd}
176
+ displayName: 'Build application'
177
+
178
+ - script: |
179
+ npm start &
180
+ sleep 10
181
+ npm run test:e2e
182
+ displayName: 'Run E2E tests'
183
+ `;
184
+ }
185
+ // Build job
186
+ content += `
187
+ - job: Build
188
+ displayName: 'Build Application'
189
+ dependsOn:
190
+ - Test
191
+ `;
192
+ if (includeSecurity &&
193
+ (strategy === "comprehensive" || strategy === "security-focused")) {
194
+ content += ` - Security
195
+ `;
196
+ }
197
+ if (includeE2E) {
198
+ content += ` - E2E
199
+ `;
200
+ }
201
+ content += ` pool:
202
+ vmImage: $(vmImageName)
203
+ steps:
204
+ - task: NodeTool@0
205
+ displayName: 'Install Node.js'
206
+ inputs:
207
+ versionSpec: '$(nodeVersion)'
208
+
209
+ - script: ${installCmd}
210
+ displayName: 'Install dependencies'
211
+
212
+ - script: ${buildCmd}
213
+ displayName: 'Build application'
214
+
215
+ - task: PublishBuildArtifacts@1
216
+ displayName: 'Publish artifacts'
217
+ inputs:
218
+ pathToPublish: 'dist'
219
+ artifactName: 'dist'
220
+
221
+ - stage: Docker
222
+ displayName: 'Docker Build & Push'
223
+ dependsOn: Build
224
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/${branch}'))
225
+ jobs:
226
+ - job: DockerBuild
227
+ displayName: 'Build & Push Docker Image'
228
+ pool:
229
+ vmImage: $(vmImageName)
230
+ steps:
231
+ - task: Docker@2
232
+ displayName: 'Build Docker image'
233
+ inputs:
234
+ containerRegistry: '$(dockerRegistryServiceConnection)'
235
+ repository: '$(imageName)'
236
+ command: 'build'
237
+ Dockerfile: '**/Dockerfile'
238
+ tags: |
239
+ $(Build.BuildId)
240
+ latest
241
+
242
+ - task: Docker@2
243
+ displayName: 'Push Docker image'
244
+ inputs:
245
+ containerRegistry: '$(dockerRegistryServiceConnection)'
246
+ repository: '$(imageName)'
247
+ command: 'push'
248
+ tags: |
249
+ $(Build.BuildId)
250
+ latest
251
+ `;
252
+ // Container scan
253
+ if (includeSecurity) {
254
+ content += `
255
+ - task: trivy@1
256
+ displayName: 'Container vulnerability scan'
257
+ inputs:
258
+ image: '$(dockerRegistry)/$(imageName):$(Build.BuildId)'
259
+ exitCode: 0
260
+ continueOnError: true
261
+ `;
262
+ }
263
+ // Deploy stage
264
+ if (deployTarget !== "none") {
265
+ content += generateAzureDeployStage(deployTarget, branch);
266
+ }
267
+ return content;
268
+ }
269
+ function generateAzureDeployStage(target, branch) {
270
+ switch (target) {
271
+ case "kubernetes":
272
+ return `
273
+ - stage: Deploy
274
+ displayName: 'Deploy to Kubernetes'
275
+ dependsOn: Docker
276
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/${branch}'))
277
+ jobs:
278
+ - deployment: DeployToK8s
279
+ displayName: 'Deploy to AKS'
280
+ pool:
281
+ vmImage: $(vmImageName)
282
+ environment: 'production'
283
+ strategy:
284
+ runOnce:
285
+ deploy:
286
+ steps:
287
+ - task: KubernetesManifest@0
288
+ displayName: 'Deploy to Kubernetes'
289
+ inputs:
290
+ action: 'deploy'
291
+ kubernetesServiceConnection: '$(kubernetesServiceConnection)'
292
+ namespace: 'default'
293
+ manifests: |
294
+ k8s/deployment.yaml
295
+ k8s/service.yaml
296
+ containers: |
297
+ $(dockerRegistry)/$(imageName):$(Build.BuildId)
298
+ `;
299
+ case "ecs":
300
+ return `
301
+ - stage: Deploy
302
+ displayName: 'Deploy to AWS ECS'
303
+ dependsOn: Docker
304
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/${branch}'))
305
+ jobs:
306
+ - deployment: DeployToECS
307
+ displayName: 'Deploy to ECS'
308
+ pool:
309
+ vmImage: $(vmImageName)
310
+ environment: 'production'
311
+ strategy:
312
+ runOnce:
313
+ deploy:
314
+ steps:
315
+ - task: AWSCLI@1
316
+ displayName: 'Update ECS Service'
317
+ inputs:
318
+ awsCredentials: '$(awsServiceConnection)'
319
+ regionName: '$(awsRegion)'
320
+ awsCommand: 'ecs'
321
+ awsSubCommand: 'update-service'
322
+ awsArguments: '--cluster $(ecsCluster) --service $(ecsService) --force-new-deployment'
323
+ `;
324
+ case "cloudrun":
325
+ return `
326
+ - stage: Deploy
327
+ displayName: 'Deploy to Cloud Run'
328
+ dependsOn: Docker
329
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/${branch}'))
330
+ jobs:
331
+ - deployment: DeployToCloudRun
332
+ displayName: 'Deploy to Cloud Run'
333
+ pool:
334
+ vmImage: $(vmImageName)
335
+ environment: 'production'
336
+ strategy:
337
+ runOnce:
338
+ deploy:
339
+ steps:
340
+ - task: GoogleCloudSdkTool@0
341
+ displayName: 'Install gcloud'
342
+
343
+ - script: |
344
+ gcloud run deploy expressots-app \\
345
+ --image $(dockerRegistry)/$(imageName):$(Build.BuildId) \\
346
+ --region $(gcpRegion) \\
347
+ --platform managed
348
+ displayName: 'Deploy to Cloud Run'
349
+ `;
350
+ default:
351
+ return `
352
+ - stage: Deploy
353
+ displayName: 'Deploy'
354
+ dependsOn: Docker
355
+ condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/${branch}'))
356
+ jobs:
357
+ - deployment: Deploy
358
+ displayName: 'Deploy to ${target}'
359
+ pool:
360
+ vmImage: $(vmImageName)
361
+ environment: 'production'
362
+ strategy:
363
+ runOnce:
364
+ deploy:
365
+ steps:
366
+ - script: echo "Deploying to ${target}"
367
+ displayName: 'Deploy'
368
+ `;
369
+ }
370
+ }
@@ -0,0 +1,2 @@
1
+ import type { GeneratorOptions } from "./github-actions";
2
+ export declare function generateBitbucketPipelines(outputDir: string, options: GeneratorOptions): Promise<void>;
@@ -0,0 +1,217 @@
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.generateBitbucketPipelines = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ const chalk_1 = __importDefault(require("chalk"));
10
+ const template_loader_1 = require("./template-loader");
11
+ async function generateBitbucketPipelines(outputDir, options) {
12
+ // Try remote template, fall back to embedded
13
+ const result = await (0, template_loader_1.loadCICDTemplate)("bitbucket", options.strategy, options, generateBitbucketContentEmbedded);
14
+ (0, template_loader_1.logTemplateSource)("Bitbucket", result.source);
15
+ const filePath = path_1.default.join(outputDir, "bitbucket-pipelines.yml");
16
+ fs_1.default.writeFileSync(filePath, result.content, "utf-8");
17
+ console.log(chalk_1.default.green(` ✓ Created bitbucket-pipelines.yml`));
18
+ }
19
+ exports.generateBitbucketPipelines = generateBitbucketPipelines;
20
+ /**
21
+ * Embedded template generator (fallback when remote templates unavailable)
22
+ */
23
+ function generateBitbucketContentEmbedded(options) {
24
+ const { nodeVersion, packageManager, strategy, includeSecurity, includeE2E, includeCoverage, deployTarget, branch, } = options;
25
+ const installCmd = packageManager === "pnpm"
26
+ ? "pnpm install"
27
+ : packageManager === "yarn"
28
+ ? "yarn install"
29
+ : "npm ci";
30
+ const testCmd = packageManager === "pnpm"
31
+ ? "pnpm test"
32
+ : packageManager === "yarn"
33
+ ? "yarn test"
34
+ : "npm test";
35
+ const buildCmd = packageManager === "pnpm"
36
+ ? "pnpm build"
37
+ : packageManager === "yarn"
38
+ ? "yarn build"
39
+ : "npm run build";
40
+ const lintCmd = packageManager === "pnpm"
41
+ ? "pnpm lint"
42
+ : packageManager === "yarn"
43
+ ? "yarn lint"
44
+ : "npm run lint";
45
+ let content = `# Bitbucket Pipelines
46
+ # Generated by ExpressoTS CLI
47
+ # Strategy: ${strategy}
48
+
49
+ image: node:${nodeVersion}
50
+
51
+ definitions:
52
+ caches:
53
+ npm: ~/.npm
54
+
55
+ steps:
56
+ - step: &lint
57
+ name: Lint
58
+ caches:
59
+ - npm
60
+ - node
61
+ script:
62
+ - ${installCmd}
63
+ - ${lintCmd}
64
+
65
+ - step: &test
66
+ name: Test
67
+ caches:
68
+ - npm
69
+ - node
70
+ script:
71
+ - ${installCmd}
72
+ - ${testCmd}${includeCoverage ? " --coverage" : ""}
73
+ `;
74
+ if (includeCoverage) {
75
+ content += ` artifacts:
76
+ - coverage/**
77
+ `;
78
+ }
79
+ content += `
80
+ - step: &build
81
+ name: Build
82
+ caches:
83
+ - npm
84
+ - node
85
+ script:
86
+ - ${installCmd}
87
+ - ${buildCmd}
88
+ artifacts:
89
+ - dist/**
90
+
91
+ - step: &docker-build
92
+ name: Docker Build & Push
93
+ services:
94
+ - docker
95
+ caches:
96
+ - docker
97
+ script:
98
+ - docker build -t \${DOCKER_IMAGE}:\${BITBUCKET_COMMIT} .
99
+ - docker tag \${DOCKER_IMAGE}:\${BITBUCKET_COMMIT} \${DOCKER_IMAGE}:latest
100
+ - echo \${DOCKER_PASSWORD} | docker login -u \${DOCKER_USERNAME} --password-stdin
101
+ - docker push \${DOCKER_IMAGE}:\${BITBUCKET_COMMIT}
102
+ - docker push \${DOCKER_IMAGE}:latest
103
+
104
+ `;
105
+ // Security step
106
+ if (includeSecurity &&
107
+ (strategy === "comprehensive" || strategy === "security-focused")) {
108
+ content += ` - step: &security
109
+ name: Security Scan
110
+ script:
111
+ - npm audit --audit-level=high || true
112
+ - pipe: aquasecurity/trivy-pipe:1.0.0
113
+ variables:
114
+ imageRef: '.'
115
+ severity: 'HIGH,CRITICAL'
116
+
117
+ `;
118
+ }
119
+ // E2E step
120
+ if (includeE2E) {
121
+ content += ` - step: &e2e
122
+ name: E2E Tests
123
+ caches:
124
+ - npm
125
+ - node
126
+ script:
127
+ - ${installCmd}
128
+ - ${buildCmd}
129
+ - npm start &
130
+ - sleep 10
131
+ - npm run test:e2e
132
+
133
+ `;
134
+ }
135
+ // Deploy step
136
+ if (deployTarget !== "none") {
137
+ content += generateBitbucketDeployStep(deployTarget);
138
+ }
139
+ // Pipelines configuration
140
+ content += `pipelines:
141
+ default:
142
+ - step: *lint
143
+ - step: *test
144
+ `;
145
+ if (includeSecurity &&
146
+ (strategy === "comprehensive" || strategy === "security-focused")) {
147
+ content += ` - step: *security
148
+ `;
149
+ }
150
+ content += ` - step: *build
151
+
152
+ branches:
153
+ ${branch}:
154
+ - step: *lint
155
+ - step: *test
156
+ `;
157
+ if (includeSecurity &&
158
+ (strategy === "comprehensive" || strategy === "security-focused")) {
159
+ content += ` - step: *security
160
+ `;
161
+ }
162
+ if (includeE2E) {
163
+ content += ` - step: *e2e
164
+ `;
165
+ }
166
+ content += ` - step: *build
167
+ - step: *docker-build
168
+ `;
169
+ if (deployTarget !== "none") {
170
+ content += ` - step: *deploy
171
+
172
+ `;
173
+ }
174
+ content += `
175
+ pull-requests:
176
+ '**':
177
+ - step: *lint
178
+ - step: *test
179
+ `;
180
+ return content;
181
+ }
182
+ function generateBitbucketDeployStep(target) {
183
+ switch (target) {
184
+ case "kubernetes":
185
+ return ` - step: &deploy
186
+ name: Deploy to Kubernetes
187
+ deployment: production
188
+ script:
189
+ - pipe: atlassian/kubectl-run:3.0.0
190
+ variables:
191
+ KUBE_CONFIG: \${KUBE_CONFIG}
192
+ KUBECTL_COMMAND: 'set image deployment/expressots-app app=\${DOCKER_IMAGE}:\${BITBUCKET_COMMIT}'
193
+ - pipe: atlassian/kubectl-run:3.0.0
194
+ variables:
195
+ KUBE_CONFIG: \${KUBE_CONFIG}
196
+ KUBECTL_COMMAND: 'rollout status deployment/expressots-app'
197
+
198
+ `;
199
+ case "railway":
200
+ return ` - step: &deploy
201
+ name: Deploy to Railway
202
+ deployment: production
203
+ script:
204
+ - npm install -g @railway/cli
205
+ - railway up
206
+
207
+ `;
208
+ default:
209
+ return ` - step: &deploy
210
+ name: Deploy
211
+ deployment: production
212
+ script:
213
+ - echo "Deploying to ${target}"
214
+
215
+ `;
216
+ }
217
+ }
@@ -0,0 +1,2 @@
1
+ import type { GeneratorOptions } from "./github-actions";
2
+ export declare function generateCircleCI(outputDir: string, options: GeneratorOptions): Promise<void>;