@launch77/cli 1.2.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 (398) hide show
  1. package/.eslintrc.json +6 -0
  2. package/dist/app-templates/webapp/.env.ci +6 -0
  3. package/dist/app-templates/webapp/.env.example +9 -0
  4. package/dist/app-templates/webapp/.eslintrc.json +6 -0
  5. package/dist/app-templates/webapp/README.md.hbs +80 -0
  6. package/dist/app-templates/webapp/app/about/page.tsx.hbs +41 -0
  7. package/dist/app-templates/webapp/app/dashboard/page.tsx.hbs +51 -0
  8. package/dist/app-templates/webapp/app/globals.css +31 -0
  9. package/dist/app-templates/webapp/app/layout.tsx.hbs +26 -0
  10. package/dist/app-templates/webapp/app/page.tsx.hbs +30 -0
  11. package/dist/app-templates/webapp/next.config.js +99 -0
  12. package/dist/app-templates/webapp/package.json.hbs +30 -0
  13. package/dist/app-templates/webapp/postcss.config.js +6 -0
  14. package/dist/app-templates/webapp/tailwind.config.ts +24 -0
  15. package/dist/app-templates/webapp/tsconfig.json +29 -0
  16. package/dist/app-templates/webapp/vercel.json.hbs +7 -0
  17. package/dist/cli.d.ts +3 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +29 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/infrastructure/filesystem.d.ts +41 -0
  22. package/dist/infrastructure/filesystem.d.ts.map +1 -0
  23. package/dist/infrastructure/filesystem.js +61 -0
  24. package/dist/infrastructure/filesystem.js.map +1 -0
  25. package/dist/infrastructure/npm.d.ts +9 -0
  26. package/dist/infrastructure/npm.d.ts.map +1 -0
  27. package/dist/infrastructure/npm.js +17 -0
  28. package/dist/infrastructure/npm.js.map +1 -0
  29. package/dist/infrastructure/template-engine.d.ts +12 -0
  30. package/dist/infrastructure/template-engine.d.ts.map +1 -0
  31. package/dist/infrastructure/template-engine.js +40 -0
  32. package/dist/infrastructure/template-engine.js.map +1 -0
  33. package/dist/infrastructure/template-generator.d.ts +9 -0
  34. package/dist/infrastructure/template-generator.d.ts.map +1 -0
  35. package/dist/infrastructure/template-generator.js +19 -0
  36. package/dist/infrastructure/template-generator.js.map +1 -0
  37. package/dist/infrastructure/template.d.ts +20 -0
  38. package/dist/infrastructure/template.d.ts.map +1 -0
  39. package/dist/infrastructure/template.js +53 -0
  40. package/dist/infrastructure/template.js.map +1 -0
  41. package/dist/modules/app/commands/create-app.d.ts +3 -0
  42. package/dist/modules/app/commands/create-app.d.ts.map +1 -0
  43. package/dist/modules/app/commands/create-app.js +51 -0
  44. package/dist/modules/app/commands/create-app.js.map +1 -0
  45. package/dist/modules/app/commands/delete-app.d.ts +3 -0
  46. package/dist/modules/app/commands/delete-app.d.ts.map +1 -0
  47. package/dist/modules/app/commands/delete-app.js +109 -0
  48. package/dist/modules/app/commands/delete-app.js.map +1 -0
  49. package/dist/modules/app/commands/generate-manifest.d.ts +3 -0
  50. package/dist/modules/app/commands/generate-manifest.d.ts.map +1 -0
  51. package/dist/modules/app/commands/generate-manifest.js +62 -0
  52. package/dist/modules/app/commands/generate-manifest.js.map +1 -0
  53. package/dist/modules/app/commands/validate-manifest.d.ts +3 -0
  54. package/dist/modules/app/commands/validate-manifest.d.ts.map +1 -0
  55. package/dist/modules/app/commands/validate-manifest.js +68 -0
  56. package/dist/modules/app/commands/validate-manifest.js.map +1 -0
  57. package/dist/modules/app/errors/app-errors.d.ts +19 -0
  58. package/dist/modules/app/errors/app-errors.d.ts.map +1 -0
  59. package/dist/modules/app/errors/app-errors.js +37 -0
  60. package/dist/modules/app/errors/app-errors.js.map +1 -0
  61. package/dist/modules/app/index.d.ts +10 -0
  62. package/dist/modules/app/index.d.ts.map +1 -0
  63. package/dist/modules/app/index.js +11 -0
  64. package/dist/modules/app/index.js.map +1 -0
  65. package/dist/modules/app/lib/manifest-schema.d.ts +39 -0
  66. package/dist/modules/app/lib/manifest-schema.d.ts.map +1 -0
  67. package/dist/modules/app/lib/manifest-schema.js +44 -0
  68. package/dist/modules/app/lib/manifest-schema.js.map +1 -0
  69. package/dist/modules/app/services/app-svc.d.ts +15 -0
  70. package/dist/modules/app/services/app-svc.d.ts.map +1 -0
  71. package/dist/modules/app/services/app-svc.js +90 -0
  72. package/dist/modules/app/services/app-svc.js.map +1 -0
  73. package/dist/modules/app/services/manifest-svc.d.ts +28 -0
  74. package/dist/modules/app/services/manifest-svc.d.ts.map +1 -0
  75. package/dist/modules/app/services/manifest-svc.js +119 -0
  76. package/dist/modules/app/services/manifest-svc.js.map +1 -0
  77. package/dist/modules/app/types/app-types.d.ts +21 -0
  78. package/dist/modules/app/types/app-types.d.ts.map +1 -0
  79. package/dist/modules/app/types/app-types.js +5 -0
  80. package/dist/modules/app/types/app-types.js.map +1 -0
  81. package/dist/modules/catalog/commands/generate.d.ts +9 -0
  82. package/dist/modules/catalog/commands/generate.d.ts.map +1 -0
  83. package/dist/modules/catalog/commands/generate.js +94 -0
  84. package/dist/modules/catalog/commands/generate.js.map +1 -0
  85. package/dist/modules/catalog/commands/scan.d.ts +9 -0
  86. package/dist/modules/catalog/commands/scan.d.ts.map +1 -0
  87. package/dist/modules/catalog/commands/scan.js +43 -0
  88. package/dist/modules/catalog/commands/scan.js.map +1 -0
  89. package/dist/modules/catalog/config/catalog-config.d.ts +49 -0
  90. package/dist/modules/catalog/config/catalog-config.d.ts.map +1 -0
  91. package/dist/modules/catalog/config/catalog-config.js +116 -0
  92. package/dist/modules/catalog/config/catalog-config.js.map +1 -0
  93. package/dist/modules/catalog/config/catalog-config.test.d.ts +2 -0
  94. package/dist/modules/catalog/config/catalog-config.test.d.ts.map +1 -0
  95. package/dist/modules/catalog/config/catalog-config.test.js +362 -0
  96. package/dist/modules/catalog/config/catalog-config.test.js.map +1 -0
  97. package/dist/modules/catalog/index.d.ts +9 -0
  98. package/dist/modules/catalog/index.d.ts.map +1 -0
  99. package/dist/modules/catalog/index.js +9 -0
  100. package/dist/modules/catalog/index.js.map +1 -0
  101. package/dist/modules/catalog/parsers/typescript-parser.d.ts +15 -0
  102. package/dist/modules/catalog/parsers/typescript-parser.d.ts.map +1 -0
  103. package/dist/modules/catalog/parsers/typescript-parser.js +82 -0
  104. package/dist/modules/catalog/parsers/typescript-parser.js.map +1 -0
  105. package/dist/modules/catalog/scanners/metadata-extractor.d.ts +10 -0
  106. package/dist/modules/catalog/scanners/metadata-extractor.d.ts.map +1 -0
  107. package/dist/modules/catalog/scanners/metadata-extractor.js +122 -0
  108. package/dist/modules/catalog/scanners/metadata-extractor.js.map +1 -0
  109. package/dist/modules/catalog/scanners/metadata-validator.d.ts +6 -0
  110. package/dist/modules/catalog/scanners/metadata-validator.d.ts.map +1 -0
  111. package/dist/modules/catalog/scanners/metadata-validator.js +57 -0
  112. package/dist/modules/catalog/scanners/metadata-validator.js.map +1 -0
  113. package/dist/modules/catalog/scanners/ui-component-scanner.d.ts +11 -0
  114. package/dist/modules/catalog/scanners/ui-component-scanner.d.ts.map +1 -0
  115. package/dist/modules/catalog/scanners/ui-component-scanner.js +147 -0
  116. package/dist/modules/catalog/scanners/ui-component-scanner.js.map +1 -0
  117. package/dist/modules/catalog/schemas/catalog-ui-components.schema.json +161 -0
  118. package/dist/modules/catalog/schemas/schemas/catalog-ui-components.schema.json +145 -0
  119. package/dist/modules/catalog/services/catalog-generator-svc.d.ts +27 -0
  120. package/dist/modules/catalog/services/catalog-generator-svc.d.ts.map +1 -0
  121. package/dist/modules/catalog/services/catalog-generator-svc.js +100 -0
  122. package/dist/modules/catalog/services/catalog-generator-svc.js.map +1 -0
  123. package/dist/modules/catalog/services/catalog-generator-svc.test.d.ts +2 -0
  124. package/dist/modules/catalog/services/catalog-generator-svc.test.d.ts.map +1 -0
  125. package/dist/modules/catalog/services/catalog-generator-svc.test.js +201 -0
  126. package/dist/modules/catalog/services/catalog-generator-svc.test.js.map +1 -0
  127. package/dist/modules/catalog/services/catalog-svc.d.ts +39 -0
  128. package/dist/modules/catalog/services/catalog-svc.d.ts.map +1 -0
  129. package/dist/modules/catalog/services/catalog-svc.js +163 -0
  130. package/dist/modules/catalog/services/catalog-svc.js.map +1 -0
  131. package/dist/modules/catalog/types/catalog-types.d.ts +120 -0
  132. package/dist/modules/catalog/types/catalog-types.d.ts.map +1 -0
  133. package/dist/modules/catalog/types/catalog-types.js +5 -0
  134. package/dist/modules/catalog/types/catalog-types.js.map +1 -0
  135. package/dist/modules/catalog/utils/examples-generator.d.ts +6 -0
  136. package/dist/modules/catalog/utils/examples-generator.d.ts.map +1 -0
  137. package/dist/modules/catalog/utils/examples-generator.js +55 -0
  138. package/dist/modules/catalog/utils/examples-generator.js.map +1 -0
  139. package/dist/modules/catalog/utils/quality-reporter.d.ts +13 -0
  140. package/dist/modules/catalog/utils/quality-reporter.d.ts.map +1 -0
  141. package/dist/modules/catalog/utils/quality-reporter.js +64 -0
  142. package/dist/modules/catalog/utils/quality-reporter.js.map +1 -0
  143. package/dist/modules/catalog/validators/component-name-validator.d.ts +20 -0
  144. package/dist/modules/catalog/validators/component-name-validator.d.ts.map +1 -0
  145. package/dist/modules/catalog/validators/component-name-validator.js +33 -0
  146. package/dist/modules/catalog/validators/component-name-validator.js.map +1 -0
  147. package/dist/modules/catalog/validators/component-name-validator.test.d.ts +2 -0
  148. package/dist/modules/catalog/validators/component-name-validator.test.d.ts.map +1 -0
  149. package/dist/modules/catalog/validators/component-name-validator.test.js +196 -0
  150. package/dist/modules/catalog/validators/component-name-validator.test.js.map +1 -0
  151. package/dist/modules/deploy/commands/deploy-init-action.d.ts +12 -0
  152. package/dist/modules/deploy/commands/deploy-init-action.d.ts.map +1 -0
  153. package/dist/modules/deploy/commands/deploy-init-action.js +220 -0
  154. package/dist/modules/deploy/commands/deploy-init-action.js.map +1 -0
  155. package/dist/modules/deploy/commands/deploy-init.d.ts +6 -0
  156. package/dist/modules/deploy/commands/deploy-init.d.ts.map +1 -0
  157. package/dist/modules/deploy/commands/deploy-init.js +16 -0
  158. package/dist/modules/deploy/commands/deploy-init.js.map +1 -0
  159. package/dist/modules/deploy/commands/deploy-logs-action.d.ts +12 -0
  160. package/dist/modules/deploy/commands/deploy-logs-action.d.ts.map +1 -0
  161. package/dist/modules/deploy/commands/deploy-logs-action.js +113 -0
  162. package/dist/modules/deploy/commands/deploy-logs-action.js.map +1 -0
  163. package/dist/modules/deploy/commands/deploy-logs.d.ts +6 -0
  164. package/dist/modules/deploy/commands/deploy-logs.d.ts.map +1 -0
  165. package/dist/modules/deploy/commands/deploy-logs.js +17 -0
  166. package/dist/modules/deploy/commands/deploy-logs.js.map +1 -0
  167. package/dist/modules/deploy/commands/deploy-status-action.d.ts +8 -0
  168. package/dist/modules/deploy/commands/deploy-status-action.d.ts.map +1 -0
  169. package/dist/modules/deploy/commands/deploy-status-action.js +153 -0
  170. package/dist/modules/deploy/commands/deploy-status-action.js.map +1 -0
  171. package/dist/modules/deploy/commands/deploy-status.d.ts +6 -0
  172. package/dist/modules/deploy/commands/deploy-status.d.ts.map +1 -0
  173. package/dist/modules/deploy/commands/deploy-status.js +13 -0
  174. package/dist/modules/deploy/commands/deploy-status.js.map +1 -0
  175. package/dist/modules/deploy/index.d.ts +7 -0
  176. package/dist/modules/deploy/index.d.ts.map +1 -0
  177. package/dist/modules/deploy/index.js +7 -0
  178. package/dist/modules/deploy/index.js.map +1 -0
  179. package/dist/modules/deploy/services/deploy-svc.d.ts +17 -0
  180. package/dist/modules/deploy/services/deploy-svc.d.ts.map +1 -0
  181. package/dist/modules/deploy/services/deploy-svc.js +25 -0
  182. package/dist/modules/deploy/services/deploy-svc.js.map +1 -0
  183. package/dist/modules/deploy/utils/vercel-extended.d.ts +63 -0
  184. package/dist/modules/deploy/utils/vercel-extended.d.ts.map +1 -0
  185. package/dist/modules/deploy/utils/vercel-extended.js +238 -0
  186. package/dist/modules/deploy/utils/vercel-extended.js.map +1 -0
  187. package/dist/modules/plugin/commands/plugin-install.d.ts +3 -0
  188. package/dist/modules/plugin/commands/plugin-install.d.ts.map +1 -0
  189. package/dist/modules/plugin/commands/plugin-install.js +45 -0
  190. package/dist/modules/plugin/commands/plugin-install.js.map +1 -0
  191. package/dist/modules/plugin/errors/plugin-errors.d.ts +16 -0
  192. package/dist/modules/plugin/errors/plugin-errors.d.ts.map +1 -0
  193. package/dist/modules/plugin/errors/plugin-errors.js +39 -0
  194. package/dist/modules/plugin/errors/plugin-errors.js.map +1 -0
  195. package/dist/modules/plugin/index.d.ts +6 -0
  196. package/dist/modules/plugin/index.d.ts.map +1 -0
  197. package/dist/modules/plugin/index.js +9 -0
  198. package/dist/modules/plugin/index.js.map +1 -0
  199. package/dist/modules/plugin/lib/plugin-registry.d.ts +15 -0
  200. package/dist/modules/plugin/lib/plugin-registry.d.ts.map +1 -0
  201. package/dist/modules/plugin/lib/plugin-registry.js +47 -0
  202. package/dist/modules/plugin/lib/plugin-registry.js.map +1 -0
  203. package/dist/modules/plugin/services/plugin-svc.d.ts +10 -0
  204. package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -0
  205. package/dist/modules/plugin/services/plugin-svc.js +44 -0
  206. package/dist/modules/plugin/services/plugin-svc.js.map +1 -0
  207. package/dist/modules/plugin/types/plugin-types.d.ts +19 -0
  208. package/dist/modules/plugin/types/plugin-types.d.ts.map +1 -0
  209. package/dist/modules/plugin/types/plugin-types.js +2 -0
  210. package/dist/modules/plugin/types/plugin-types.js.map +1 -0
  211. package/dist/modules/startup/commands/create-startup.d.ts +3 -0
  212. package/dist/modules/startup/commands/create-startup.d.ts.map +1 -0
  213. package/dist/modules/startup/commands/create-startup.js +43 -0
  214. package/dist/modules/startup/commands/create-startup.js.map +1 -0
  215. package/dist/modules/startup/errors/startup-errors.d.ts +13 -0
  216. package/dist/modules/startup/errors/startup-errors.d.ts.map +1 -0
  217. package/dist/modules/startup/errors/startup-errors.js +25 -0
  218. package/dist/modules/startup/errors/startup-errors.js.map +1 -0
  219. package/dist/modules/startup/index.d.ts +5 -0
  220. package/dist/modules/startup/index.d.ts.map +1 -0
  221. package/dist/modules/startup/index.js +7 -0
  222. package/dist/modules/startup/index.js.map +1 -0
  223. package/dist/modules/startup/services/startup-service.d.ts +7 -0
  224. package/dist/modules/startup/services/startup-service.d.ts.map +1 -0
  225. package/dist/modules/startup/services/startup-service.js +43 -0
  226. package/dist/modules/startup/services/startup-service.js.map +1 -0
  227. package/dist/modules/startup/types/startup-types.d.ts +8 -0
  228. package/dist/modules/startup/types/startup-types.d.ts.map +1 -0
  229. package/dist/modules/startup/types/startup-types.js +2 -0
  230. package/dist/modules/startup/types/startup-types.js.map +1 -0
  231. package/dist/modules/startup/utils/startup-validators.d.ts +8 -0
  232. package/dist/modules/startup/utils/startup-validators.d.ts.map +1 -0
  233. package/dist/modules/startup/utils/startup-validators.js +17 -0
  234. package/dist/modules/startup/utils/startup-validators.js.map +1 -0
  235. package/dist/modules/workspace/commands/init-workspace.d.ts +3 -0
  236. package/dist/modules/workspace/commands/init-workspace.d.ts.map +1 -0
  237. package/dist/modules/workspace/commands/init-workspace.js +54 -0
  238. package/dist/modules/workspace/commands/init-workspace.js.map +1 -0
  239. package/dist/modules/workspace/errors/workspace-errors.d.ts +10 -0
  240. package/dist/modules/workspace/errors/workspace-errors.d.ts.map +1 -0
  241. package/dist/modules/workspace/errors/workspace-errors.js +19 -0
  242. package/dist/modules/workspace/errors/workspace-errors.js.map +1 -0
  243. package/dist/modules/workspace/index.d.ts +5 -0
  244. package/dist/modules/workspace/index.d.ts.map +1 -0
  245. package/dist/modules/workspace/index.js +7 -0
  246. package/dist/modules/workspace/index.js.map +1 -0
  247. package/dist/modules/workspace/services/workspace-service.d.ts +6 -0
  248. package/dist/modules/workspace/services/workspace-service.d.ts.map +1 -0
  249. package/dist/modules/workspace/services/workspace-service.js +46 -0
  250. package/dist/modules/workspace/services/workspace-service.js.map +1 -0
  251. package/dist/modules/workspace/types/workspace-types.d.ts +8 -0
  252. package/dist/modules/workspace/types/workspace-types.d.ts.map +1 -0
  253. package/dist/modules/workspace/types/workspace-types.js +2 -0
  254. package/dist/modules/workspace/types/workspace-types.js.map +1 -0
  255. package/dist/modules/workspace/utils/workspace-validators.d.ts +8 -0
  256. package/dist/modules/workspace/utils/workspace-validators.d.ts.map +1 -0
  257. package/dist/modules/workspace/utils/workspace-validators.js +17 -0
  258. package/dist/modules/workspace/utils/workspace-validators.js.map +1 -0
  259. package/dist/plugins/theme/package.json +32 -0
  260. package/dist/plugins/theme/plugin.json +9 -0
  261. package/dist/plugins/theme/src/generator.ts +92 -0
  262. package/dist/plugins/theme/src/utils/config-modifier.ts +142 -0
  263. package/dist/plugins/theme/src/utils/css-modifier.ts +89 -0
  264. package/dist/plugins/theme/templates/app/theme-test/page.tsx +156 -0
  265. package/dist/plugins/theme/templates/src/modules/theme/README.md +209 -0
  266. package/dist/plugins/theme/templates/src/modules/theme/config/brand.css +23 -0
  267. package/dist/plugins/theme/tsconfig.json +14 -0
  268. package/dist/plugins/theme/tsup.config.ts +10 -0
  269. package/dist/templates/startup/apps/.gitkeep +8 -0
  270. package/dist/templates/templates/startup/apps/.gitkeep +8 -0
  271. package/dist/templates/templates/workspace/.eslintignore +7 -0
  272. package/dist/templates/templates/workspace/.eslintrc.js +38 -0
  273. package/dist/templates/templates/workspace/.husky/pre-push +24 -0
  274. package/dist/templates/templates/workspace/.launch77/workspace.json +3 -0
  275. package/dist/templates/templates/workspace/.lintstagedrc.json +4 -0
  276. package/dist/templates/templates/workspace/.prettierrc +9 -0
  277. package/dist/templates/templates/workspace/README.md +62 -0
  278. package/dist/templates/templates/workspace/app-templates/.gitkeep +1 -0
  279. package/dist/templates/templates/workspace/apps/.gitkeep +1 -0
  280. package/dist/templates/templates/workspace/libraries/.gitkeep +1 -0
  281. package/dist/templates/templates/workspace/package.json +31 -0
  282. package/dist/templates/templates/workspace/plugins/.gitkeep +1 -0
  283. package/dist/templates/templates/workspace/tsconfig.json +22 -0
  284. package/dist/templates/templates/workspace/turbo.json +25 -0
  285. package/dist/templates/workspace/.launch77/workspace.json +3 -0
  286. package/dist/templates/workspace/README.md +62 -0
  287. package/dist/templates/workspace/app-templates/.gitkeep +1 -0
  288. package/dist/templates/workspace/apps/.gitkeep +1 -0
  289. package/dist/templates/workspace/libraries/.gitkeep +1 -0
  290. package/dist/templates/workspace/package.json +21 -0
  291. package/dist/templates/workspace/plugins/.gitkeep +1 -0
  292. package/dist/templates/workspace/tsconfig.json +22 -0
  293. package/dist/templates/workspace/turbo.json +25 -0
  294. package/dist/utils/launch77-context.d.ts +16 -0
  295. package/dist/utils/launch77-context.d.ts.map +1 -0
  296. package/dist/utils/launch77-context.js +111 -0
  297. package/dist/utils/launch77-context.js.map +1 -0
  298. package/dist/utils/launch77-validation.d.ts +17 -0
  299. package/dist/utils/launch77-validation.d.ts.map +1 -0
  300. package/dist/utils/launch77-validation.js +44 -0
  301. package/dist/utils/launch77-validation.js.map +1 -0
  302. package/dist/utils/monorepo.d.ts +19 -0
  303. package/dist/utils/monorepo.d.ts.map +1 -0
  304. package/dist/utils/monorepo.js +100 -0
  305. package/dist/utils/monorepo.js.map +1 -0
  306. package/dist/utils/validation.d.ts +32 -0
  307. package/dist/utils/validation.d.ts.map +1 -0
  308. package/dist/utils/validation.js +92 -0
  309. package/dist/utils/validation.js.map +1 -0
  310. package/dist/utils/version.d.ts +7 -0
  311. package/dist/utils/version.d.ts.map +1 -0
  312. package/dist/utils/version.js +16 -0
  313. package/dist/utils/version.js.map +1 -0
  314. package/launch77-cli-1.2.0.tgz +0 -0
  315. package/package.json +48 -0
  316. package/src/cli.ts +34 -0
  317. package/src/infrastructure/filesystem.ts +69 -0
  318. package/src/infrastructure/npm.ts +18 -0
  319. package/src/infrastructure/template-engine.ts +48 -0
  320. package/src/infrastructure/template-generator.ts +26 -0
  321. package/src/infrastructure/template.ts +66 -0
  322. package/src/modules/app/commands/create-app.ts +60 -0
  323. package/src/modules/app/commands/delete-app.ts +123 -0
  324. package/src/modules/app/commands/generate-manifest.ts +75 -0
  325. package/src/modules/app/commands/validate-manifest.ts +78 -0
  326. package/src/modules/app/errors/app-errors.ts +41 -0
  327. package/src/modules/app/index.ts +16 -0
  328. package/src/modules/app/lib/manifest-schema.ts +65 -0
  329. package/src/modules/app/services/app-svc.ts +115 -0
  330. package/src/modules/app/services/manifest-svc.ts +144 -0
  331. package/src/modules/app/types/app-types.ts +27 -0
  332. package/src/modules/catalog/commands/generate.ts +115 -0
  333. package/src/modules/catalog/commands/scan.ts +48 -0
  334. package/src/modules/catalog/config/catalog-config.test.ts +404 -0
  335. package/src/modules/catalog/config/catalog-config.ts +130 -0
  336. package/src/modules/catalog/index.ts +9 -0
  337. package/src/modules/catalog/parsers/typescript-parser.ts +93 -0
  338. package/src/modules/catalog/scanners/metadata-extractor.ts +134 -0
  339. package/src/modules/catalog/scanners/metadata-validator.ts +67 -0
  340. package/src/modules/catalog/scanners/ui-component-scanner.ts +185 -0
  341. package/src/modules/catalog/schemas/catalog-ui-components.schema.json +145 -0
  342. package/src/modules/catalog/services/catalog-generator-svc.test.ts +233 -0
  343. package/src/modules/catalog/services/catalog-generator-svc.ts +124 -0
  344. package/src/modules/catalog/services/catalog-svc.ts +222 -0
  345. package/src/modules/catalog/types/catalog-types.ts +149 -0
  346. package/src/modules/catalog/utils/examples-generator.ts +68 -0
  347. package/src/modules/catalog/utils/quality-reporter.ts +76 -0
  348. package/src/modules/catalog/validators/component-name-validator.test.ts +233 -0
  349. package/src/modules/catalog/validators/component-name-validator.ts +43 -0
  350. package/src/modules/deploy/commands/deploy-init-action.ts +247 -0
  351. package/src/modules/deploy/commands/deploy-init.ts +19 -0
  352. package/src/modules/deploy/commands/deploy-logs-action.ts +135 -0
  353. package/src/modules/deploy/commands/deploy-logs.ts +20 -0
  354. package/src/modules/deploy/commands/deploy-status-action.ts +175 -0
  355. package/src/modules/deploy/commands/deploy-status.ts +16 -0
  356. package/src/modules/deploy/index.ts +7 -0
  357. package/src/modules/deploy/services/deploy-svc.ts +31 -0
  358. package/src/modules/deploy/utils/vercel-extended.ts +286 -0
  359. package/src/modules/plugin/commands/plugin-install.ts +51 -0
  360. package/src/modules/plugin/errors/plugin-errors.ts +44 -0
  361. package/src/modules/plugin/index.ts +14 -0
  362. package/src/modules/plugin/lib/launch77-workspace.code-workspace +14 -0
  363. package/src/modules/plugin/lib/plugin-registry.ts +59 -0
  364. package/src/modules/plugin/services/plugin-svc.ts +53 -0
  365. package/src/modules/plugin/types/plugin-types.ts +21 -0
  366. package/src/modules/startup/commands/create-startup.ts +53 -0
  367. package/src/modules/startup/errors/startup-errors.ts +23 -0
  368. package/src/modules/startup/index.ts +11 -0
  369. package/src/modules/startup/services/startup-service.ts +57 -0
  370. package/src/modules/startup/types/startup-types.ts +8 -0
  371. package/src/modules/startup/utils/startup-validators.ts +19 -0
  372. package/src/modules/workspace/commands/init-workspace.ts +63 -0
  373. package/src/modules/workspace/errors/workspace-errors.ts +16 -0
  374. package/src/modules/workspace/index.ts +11 -0
  375. package/src/modules/workspace/services/workspace-service.ts +59 -0
  376. package/src/modules/workspace/types/workspace-types.ts +8 -0
  377. package/src/modules/workspace/utils/workspace-validators.ts +19 -0
  378. package/src/utils/launch77-context.ts +152 -0
  379. package/src/utils/launch77-validation.ts +59 -0
  380. package/src/utils/monorepo.ts +137 -0
  381. package/src/utils/validation.ts +117 -0
  382. package/src/utils/version.ts +16 -0
  383. package/templates/startup/apps/.gitkeep +8 -0
  384. package/templates/workspace/.eslintignore +7 -0
  385. package/templates/workspace/.eslintrc.js +38 -0
  386. package/templates/workspace/.husky/pre-push +24 -0
  387. package/templates/workspace/.launch77/workspace.json +3 -0
  388. package/templates/workspace/.lintstagedrc.json +4 -0
  389. package/templates/workspace/.prettierrc +9 -0
  390. package/templates/workspace/README.md +62 -0
  391. package/templates/workspace/app-templates/.gitkeep +1 -0
  392. package/templates/workspace/apps/.gitkeep +1 -0
  393. package/templates/workspace/libraries/.gitkeep +1 -0
  394. package/templates/workspace/package.json +31 -0
  395. package/templates/workspace/plugins/.gitkeep +1 -0
  396. package/templates/workspace/tsconfig.json +22 -0
  397. package/templates/workspace/turbo.json +25 -0
  398. package/tsconfig.json +23 -0
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Get the version from package.json
3
+ * @param importMetaUrl - Pass import.meta.url from the calling module
4
+ * @returns Version string from package.json
5
+ */
6
+ export declare function getPackageVersion(importMetaUrl: string): string;
7
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAM/D"}
@@ -0,0 +1,16 @@
1
+ import { readFileSync } from 'fs';
2
+ import { dirname, join } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ /**
5
+ * Get the version from package.json
6
+ * @param importMetaUrl - Pass import.meta.url from the calling module
7
+ * @returns Version string from package.json
8
+ */
9
+ export function getPackageVersion(importMetaUrl) {
10
+ const __filename = fileURLToPath(importMetaUrl);
11
+ const __dirname = dirname(__filename);
12
+ const packageJsonPath = join(__dirname, '../package.json');
13
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
14
+ return packageJson.version;
15
+ }
16
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/utils/version.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAA;AAEnC;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAqB;IACrD,MAAM,UAAU,GAAG,aAAa,CAAC,aAAa,CAAC,CAAA;IAC/C,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;IACrC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;IAC1D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAA;IACtE,OAAO,WAAW,CAAC,OAAO,CAAA;AAC5B,CAAC"}
Binary file
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@launch77/cli",
3
+ "version": "1.2.0",
4
+ "description": "Launch77 Platform CLI - Refactored",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "bin": {
8
+ "launch77": "./dist/cli.js"
9
+ },
10
+ "publishConfig": {
11
+ "access": "public"
12
+ },
13
+ "scripts": {
14
+ "build": "tsc && chmod +x dist/cli.js && cp -r templates dist/templates && cp -r src/modules/catalog/schemas dist/modules/catalog/schemas",
15
+ "dev": "tsx src/cli.ts",
16
+ "typecheck": "tsc --noEmit",
17
+ "lint": "eslint src/**/*.ts",
18
+ "lint:fix": "eslint src/**/*.ts --fix"
19
+ },
20
+ "dependencies": {
21
+ "@types/inquirer": "^9.0.9",
22
+ "chalk": "^5.3.0",
23
+ "commander": "^11.1.0",
24
+ "execa": "^8.0.1",
25
+ "fs-extra": "^11.2.0",
26
+ "handlebars": "^4.7.8",
27
+ "inquirer": "^13.0.2",
28
+ "ora": "^8.0.1",
29
+ "zod": "^4.1.13"
30
+ },
31
+ "devDependencies": {
32
+ "@types/fs-extra": "^11.0.4",
33
+ "@types/node": "^20.10.6",
34
+ "@typescript-eslint/eslint-plugin": "^6.17.0",
35
+ "@typescript-eslint/parser": "^6.17.0",
36
+ "eslint": "^8.56.0",
37
+ "prettier": "^3.7.4",
38
+ "tsx": "^4.7.0",
39
+ "typescript": "^5.3.3",
40
+ "vitest": "^4.0.16"
41
+ },
42
+ "workspaces": [
43
+ "apps/*",
44
+ "libraries/*",
45
+ "plugins/*",
46
+ "app-templates/*"
47
+ ]
48
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,34 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander'
4
+
5
+ import { createAppCommand, deleteAppCommand, generateManifestCommand, validateManifestCommand } from './modules/app/index.js'
6
+ import { scanCommand, createGenerateCommand } from './modules/catalog/index.js'
7
+ import { deployInitCommand, deployLogsCommand, deployStatusCommand } from './modules/deploy/index.js'
8
+ import { pluginInstallCommand } from './modules/plugin/index.js'
9
+ import { createStartupCommand } from './modules/startup/index.js'
10
+ import { getPackageVersion } from './utils/version.js'
11
+ import { initWorkspaceCommand } from './modules/workspace/index.js'
12
+
13
+ const program = new Command()
14
+ .name('launch77')
15
+ .description('Launch77 Platform CLI')
16
+ .version(getPackageVersion(import.meta.url))
17
+
18
+ // Register module commands
19
+ program.addCommand(initWorkspaceCommand())
20
+ program.addCommand(createStartupCommand())
21
+ program.addCommand(createAppCommand())
22
+ program.addCommand(deleteAppCommand())
23
+ program.addCommand(generateManifestCommand())
24
+ program.addCommand(validateManifestCommand())
25
+ program.addCommand(pluginInstallCommand())
26
+ program.addCommand(scanCommand())
27
+ program.addCommand(createGenerateCommand())
28
+
29
+ // Deploy commands
30
+ program.addCommand(deployInitCommand())
31
+ program.addCommand(deployStatusCommand())
32
+ program.addCommand(deployLogsCommand())
33
+
34
+ program.parse()
@@ -0,0 +1,69 @@
1
+ import fs from 'fs-extra'
2
+
3
+ /**
4
+ * Check if a file or directory exists
5
+ */
6
+ export async function exists(path: string): Promise<boolean> {
7
+ return fs.pathExists(path)
8
+ }
9
+
10
+ /**
11
+ * Ensure a directory exists, creating it if necessary
12
+ */
13
+ export async function ensureDir(path: string): Promise<void> {
14
+ await fs.ensureDir(path)
15
+ }
16
+
17
+ /**
18
+ * Write a file with content
19
+ */
20
+ export async function writeFile(path: string, content: string): Promise<void> {
21
+ await fs.writeFile(path, content, 'utf-8')
22
+ }
23
+
24
+ /**
25
+ * Write JSON to a file with formatting
26
+ */
27
+ export async function writeJSON(path: string, data: unknown, spaces = 2): Promise<void> {
28
+ await fs.writeJSON(path, data, { spaces })
29
+ }
30
+
31
+ /**
32
+ * Read a file's content
33
+ */
34
+ export async function readFile(path: string): Promise<string> {
35
+ return fs.readFile(path, 'utf-8')
36
+ }
37
+
38
+ /**
39
+ * Read JSON from a file
40
+ */
41
+ export async function readJSON<T = unknown>(path: string): Promise<T> {
42
+ return fs.readJSON(path)
43
+ }
44
+
45
+ /**
46
+ * Copy a file or directory
47
+ */
48
+ export async function copy(src: string, dest: string): Promise<void> {
49
+ await fs.copy(src, dest)
50
+ }
51
+
52
+ /**
53
+ * Read directory contents
54
+ */
55
+ export async function readdir(path: string): Promise<string[]> {
56
+ return fs.readdir(path)
57
+ }
58
+
59
+ /**
60
+ * Read directory with file types
61
+ */
62
+ export async function readdirWithTypes(path: string): Promise<Array<{ name: string; isDirectory: boolean; isFile: boolean }>> {
63
+ const entries = await fs.readdir(path, { withFileTypes: true })
64
+ return entries.map((entry) => ({
65
+ name: entry.name,
66
+ isDirectory: entry.isDirectory(),
67
+ isFile: entry.isFile(),
68
+ }))
69
+ }
@@ -0,0 +1,18 @@
1
+ import { execa } from 'execa'
2
+
3
+ /**
4
+ * Run npm install in a directory
5
+ */
6
+ export async function runNpmInstall(cwd: string): Promise<void> {
7
+ await execa('npm', ['install'], {
8
+ cwd,
9
+ stdio: 'pipe',
10
+ })
11
+ }
12
+
13
+ /**
14
+ * Alias for runNpmInstall
15
+ */
16
+ export async function install(cwd: string): Promise<void> {
17
+ await runNpmInstall(cwd)
18
+ }
@@ -0,0 +1,48 @@
1
+ import * as path from 'path'
2
+
3
+ import Handlebars from 'handlebars'
4
+
5
+ import * as filesystem from './filesystem.js'
6
+
7
+ export interface TemplateContext {
8
+ [key: string]: string | number | boolean | undefined
9
+ }
10
+
11
+ /**
12
+ * Process a single template string with Handlebars
13
+ */
14
+ export function processTemplateString(template: string, context: TemplateContext): string {
15
+ const compiledTemplate = Handlebars.compile(template)
16
+ return compiledTemplate(context)
17
+ }
18
+
19
+ /**
20
+ * Process a template directory by copying it to a destination and processing .hbs files
21
+ */
22
+ export async function processTemplate(templatePath: string, destinationPath: string, context: TemplateContext): Promise<void> {
23
+ // Ensure destination exists
24
+ await filesystem.ensureDir(destinationPath)
25
+
26
+ // Read all items in template directory
27
+ const items = await filesystem.readdirWithTypes(templatePath)
28
+
29
+ for (const item of items) {
30
+ const sourcePath = path.join(templatePath, item.name)
31
+ const isHandlebarsFile = item.name.endsWith('.hbs')
32
+ const targetName = isHandlebarsFile ? item.name.replace(/\.hbs$/, '') : item.name
33
+ const targetPath = path.join(destinationPath, targetName)
34
+
35
+ if (item.isDirectory) {
36
+ // Recursively process directories
37
+ await processTemplate(sourcePath, targetPath, context)
38
+ } else if (isHandlebarsFile) {
39
+ // Process Handlebars template
40
+ const templateContent = await filesystem.readFile(sourcePath)
41
+ const processedContent = processTemplateString(templateContent, context)
42
+ await filesystem.writeFile(targetPath, processedContent)
43
+ } else {
44
+ // Copy file as-is
45
+ await filesystem.copy(sourcePath, targetPath)
46
+ }
47
+ }
48
+ }
@@ -0,0 +1,26 @@
1
+ import { getTemplatePath, processTemplate, templateExists } from './template.js'
2
+
3
+ import type { Launch77Context } from '../utils/launch77-context.js'
4
+
5
+ export interface GenerateFromTemplateOptions {
6
+ port?: string
7
+ }
8
+
9
+ /**
10
+ * Generate an app from a template
11
+ */
12
+ export async function generateFromTemplate(type: string, appPath: string, appName: string, context: Launch77Context, options: GenerateFromTemplateOptions): Promise<void> {
13
+ // Check if template exists
14
+ if (!(await templateExists(type))) throw new Error(`Template not found for type: ${type}`)
15
+
16
+ // Get template path
17
+ const templatePath = getTemplatePath(type)
18
+
19
+ // Process template with context
20
+ await processTemplate(templatePath, appPath, {
21
+ appName,
22
+ workspaceName: context.workspaceName,
23
+ packageName: context.packageName,
24
+ port: options.port,
25
+ })
26
+ }
@@ -0,0 +1,66 @@
1
+ import * as path from 'path'
2
+ import { fileURLToPath } from 'url'
3
+
4
+ import fs from 'fs-extra'
5
+ import Handlebars from 'handlebars'
6
+
7
+ export interface TemplateContext {
8
+ appName: string
9
+ startupName?: string
10
+ port?: string
11
+ [key: string]: string | number | boolean | undefined
12
+ }
13
+
14
+ /**
15
+ * Process a template directory by copying it to a destination and processing .hbs files
16
+ */
17
+ export async function processTemplate(templatePath: string, destinationPath: string, context: TemplateContext): Promise<void> {
18
+ // Ensure destination exists
19
+ await fs.ensureDir(destinationPath)
20
+
21
+ // Read all items in template directory
22
+ const items = await fs.readdir(templatePath, { withFileTypes: true })
23
+
24
+ for (const item of items) {
25
+ const sourcePath = path.join(templatePath, item.name)
26
+ const isHandlebarsFile = item.name.endsWith('.hbs')
27
+ const targetName = isHandlebarsFile ? item.name.replace(/\.hbs$/, '') : item.name
28
+ const targetPath = path.join(destinationPath, targetName)
29
+
30
+ if (item.isDirectory()) {
31
+ // Recursively process directories
32
+ await processTemplate(sourcePath, targetPath, context)
33
+ } else if (isHandlebarsFile) {
34
+ // Process Handlebars template
35
+ const templateContent = await fs.readFile(sourcePath, 'utf-8')
36
+ const template = Handlebars.compile(templateContent)
37
+ const processedContent = template(context)
38
+ await fs.writeFile(targetPath, processedContent, 'utf-8')
39
+ } else {
40
+ // Copy file as-is
41
+ await fs.copy(sourcePath, targetPath)
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * Get the path to a template directory
48
+ * Templates are always in dist/app-templates/ (copied during build)
49
+ */
50
+ export function getTemplatePath(templateName: string): string {
51
+ const __filename = fileURLToPath(import.meta.url)
52
+ const __dirname = path.dirname(__filename)
53
+
54
+ // From dist/infrastructure/ to dist/app-templates/
55
+ const baseDir = path.join(__dirname, '../app-templates')
56
+
57
+ return path.join(baseDir, templateName)
58
+ }
59
+
60
+ /**
61
+ * Check if a template exists
62
+ */
63
+ export async function templateExists(templateName: string): Promise<boolean> {
64
+ const templatePath = getTemplatePath(templateName)
65
+ return fs.pathExists(templatePath)
66
+ }
@@ -0,0 +1,60 @@
1
+ /* eslint-disable no-console */
2
+ import * as path from 'path'
3
+
4
+ import chalk from 'chalk'
5
+ import { Command } from 'commander'
6
+ import ora from 'ora'
7
+
8
+ import { detectLaunch77Context } from '../../../utils/launch77-context.js'
9
+ import { AppService } from '../services/app-svc.js'
10
+ import { APP_TYPES, APP_TYPES_LIST } from '../types/app-types.js'
11
+
12
+ import type { AppType } from '../types/app-types.js'
13
+
14
+ export function createAppCommand(): Command {
15
+ const command = new Command('app:create')
16
+ .argument('<type>', 'App type (api, webapp, marketing-site)')
17
+ .argument('<app-name>', 'Name of the application')
18
+ .description('Create a new application')
19
+ .option('-p, --port <port>', 'Default port for the app')
20
+ .action(async (type: string, appName: string, options) => {
21
+ try {
22
+ // Validate app type
23
+ if (!APP_TYPES.includes(type as AppType)) {
24
+ throw new Error(`Invalid app type: ${type}\n\nSupported types: ${APP_TYPES_LIST}`)
25
+ }
26
+
27
+ console.log(chalk.blue(`\n🚀 Creating ${type} app: ${appName}\n`))
28
+
29
+ // Set default port based on app type
30
+ const port = options.port || (type === 'marketing-site' || type === 'webapp' ? '3000' : '4000')
31
+
32
+ // Detect context
33
+ const context = await detectLaunch77Context(process.cwd())
34
+
35
+ // Create app service
36
+ const appService = new AppService()
37
+
38
+ // Generate from template
39
+ const templateSpinner = ora('Generating app structure...').start()
40
+ let result
41
+ try {
42
+ result = await appService.createApp({ type: type as AppType, appName, port }, context)
43
+ templateSpinner.succeed('App structure generated')
44
+ } catch (error) {
45
+ templateSpinner.fail('Failed to generate app structure')
46
+ throw error
47
+ }
48
+
49
+ // Success message
50
+ console.log(chalk.green(`\n✅ App created successfully at ${path.relative(process.cwd(), result.appPath)}`))
51
+ console.log(chalk.gray(`\nRun 'npm run dev' from workspace root to start the server at http://localhost:${port}\n`))
52
+ } catch (error) {
53
+ const message = error instanceof Error ? error.message : String(error)
54
+ console.error(chalk.red('Error:'), message)
55
+ process.exit(1)
56
+ }
57
+ })
58
+
59
+ return command
60
+ }
@@ -0,0 +1,123 @@
1
+ /* eslint-disable no-console */
2
+ import * as path from 'path'
3
+
4
+ import chalk from 'chalk'
5
+ import { Command } from 'commander'
6
+ import inquirer from 'inquirer'
7
+ import ora from 'ora'
8
+
9
+ import { detectLaunch77Context } from '../../../utils/launch77-context.js'
10
+ import { AppService } from '../services/app-svc.js'
11
+
12
+ export function deleteAppCommand(): Command {
13
+ const command = new Command('app:delete')
14
+ .argument('<app-name>', 'Name of the app to delete')
15
+ .description('Delete an app from the startup (requires confirmation)')
16
+ .action(async (appName: string) => {
17
+ try {
18
+ console.log(chalk.yellow(`\n⚠️ WARNING: You are about to delete the app '${appName}'\n`))
19
+
20
+ // Detect context
21
+ const context = await detectLaunch77Context(process.cwd())
22
+
23
+ // Create app service
24
+ const appService = new AppService()
25
+
26
+ // Get app path for display (before deletion)
27
+ const appPath = path.join(context.appsDir, appName)
28
+
29
+ // Display what will be deleted
30
+ console.log(chalk.red('App location:'), appPath)
31
+ console.log(chalk.red('\nThis will permanently delete:'))
32
+ console.log(chalk.gray(' • All source code and configuration files'))
33
+ console.log(chalk.gray(' • All node_modules (will be cleaned from monorepo)'))
34
+ console.log(chalk.gray(' • All build artifacts'))
35
+
36
+ console.log(chalk.red('\n⚠️ THIS ACTION CANNOT BE UNDONE!\n'))
37
+
38
+ // First confirmation: Type app name
39
+ const { confirmName } = await inquirer.prompt([
40
+ {
41
+ type: 'input',
42
+ name: 'confirmName',
43
+ message: `Type the app name to confirm:`,
44
+ validate: (input: string) => {
45
+ if (input === appName) {
46
+ return true
47
+ }
48
+ return `Please type '${appName}' exactly to confirm`
49
+ },
50
+ },
51
+ ])
52
+
53
+ if (confirmName !== appName) {
54
+ console.log(chalk.gray('\n✖ Deletion cancelled\n'))
55
+ return
56
+ }
57
+
58
+ // Second confirmation: Type DELETE
59
+ const { confirmDelete } = await inquirer.prompt([
60
+ {
61
+ type: 'input',
62
+ name: 'confirmDelete',
63
+ message: 'Type DELETE (all caps) to confirm permanent deletion:',
64
+ validate: (input: string) => {
65
+ if (input === 'DELETE') {
66
+ return true
67
+ }
68
+ return 'Please type DELETE (all caps) to confirm'
69
+ },
70
+ },
71
+ ])
72
+
73
+ if (confirmDelete !== 'DELETE') {
74
+ console.log(chalk.gray('\n✖ Deletion cancelled\n'))
75
+ return
76
+ }
77
+
78
+ // Delete the app
79
+ const deleteSpinner = ora('Deleting app directory...').start()
80
+ let result
81
+ try {
82
+ result = await appService.deleteApp({ appName }, context)
83
+ deleteSpinner.succeed('App directory deleted')
84
+ } catch (error) {
85
+ deleteSpinner.fail('Failed to delete app directory')
86
+ throw error
87
+ }
88
+
89
+ // Update dependencies
90
+ const installSpinner = ora('Updating workspace dependencies...').start()
91
+ try {
92
+ // This is already done by app service, just show spinner for consistency
93
+ installSpinner.succeed('Dependencies updated (package-lock.json cleaned)')
94
+ } catch (error) {
95
+ installSpinner.fail('Failed to update dependencies')
96
+ console.log(chalk.yellow('\n⚠️ You may need to run "npm install" manually at the workspace root\n'))
97
+ }
98
+
99
+ // Success message
100
+ console.log(chalk.green(`\n✅ App '${appName}' has been deleted\n`))
101
+
102
+ // Reminder about Docker cleanup
103
+ if (result.hadDockerResources) {
104
+ console.log(chalk.yellow('📝 Remember to clean up Docker resources if needed:'))
105
+ console.log(chalk.gray(' • Stop and remove containers: docker ps -a | grep ' + appName))
106
+ console.log(chalk.gray(' • Remove volumes: docker volume ls | grep ' + appName))
107
+ console.log(chalk.gray(' • Use: docker-compose down -v (if you saved the compose file)\n'))
108
+ }
109
+
110
+ // Reminder about Git
111
+ console.log(chalk.yellow('📝 Remember to commit the deletion:'))
112
+ console.log(chalk.gray(' git add -A'))
113
+ console.log(chalk.gray(` git commit -m "Remove ${appName} app"`))
114
+ console.log()
115
+ } catch (error) {
116
+ const message = error instanceof Error ? error.message : String(error)
117
+ console.error(chalk.red('Error:'), message)
118
+ process.exit(1)
119
+ }
120
+ })
121
+
122
+ return command
123
+ }
@@ -0,0 +1,75 @@
1
+ /* eslint-disable no-console */
2
+ import * as path from 'path'
3
+
4
+ import chalk from 'chalk'
5
+ import { Command } from 'commander'
6
+ import fs from 'fs-extra'
7
+ import ora from 'ora'
8
+
9
+ import { detectLaunch77Context } from '../../../utils/launch77-context.js'
10
+ import { ManifestService } from '../services/manifest-svc.js'
11
+ import { APP_TYPES, APP_TYPES_LIST, AppType } from '../types/app-types.js'
12
+
13
+ export function generateManifestCommand(): Command {
14
+ const command = new Command('app:generate-manifest')
15
+ .description('Generate a manifest for an existing app (run from app directory)')
16
+ .requiredOption('-t, --type <type>', `App type (${APP_TYPES_LIST})`)
17
+ .option('-p, --port <port>', 'Port for API apps (defaults to 4000)')
18
+ .option('-f, --force', 'Overwrite existing manifest')
19
+ .action(async (options) => {
20
+ try {
21
+ const context = await detectLaunch77Context(process.cwd())
22
+
23
+ if (context.locationType !== 'workspace-app') {
24
+ throw new Error('Must be run from within an app directory (e.g., apps/myapp)')
25
+ }
26
+
27
+ // Validate app type
28
+ if (!APP_TYPES.includes(options.type as AppType)) {
29
+ throw new Error(`Invalid app type: ${options.type}. Supported types: ${APP_TYPES_LIST}`)
30
+ }
31
+
32
+ const appPath = process.cwd()
33
+ const appName = context.appName!
34
+
35
+ console.log(chalk.blue(`\n🔍 Generating manifest for app: ${appName}\n`))
36
+
37
+ // Check if manifest already exists
38
+ const launchDir = path.join(appPath, '.launch')
39
+ const manifestPath = path.join(launchDir, 'app.json')
40
+
41
+ if ((await fs.pathExists(manifestPath)) && !options.force) {
42
+ console.log(chalk.yellow('⚠️ Manifest already exists at .launch/app.json'))
43
+ console.log(chalk.gray('Use --force to overwrite'))
44
+ return
45
+ }
46
+
47
+ // Get port
48
+ const port = options.port || (options.type === 'api' ? '4000' : '3000')
49
+
50
+ // Generate manifest
51
+ const manifestSpinner = ora('Generating manifest...').start()
52
+ const manifestService = new ManifestService()
53
+ const manifest = manifestService.generateManifest(options.type, appName, context, { port })
54
+
55
+ // Ensure .launch directory exists
56
+ await fs.ensureDir(launchDir)
57
+
58
+ // Write manifest
59
+ await fs.writeJSON(manifestPath, manifest, { spaces: 2 })
60
+ manifestSpinner.succeed('Manifest generated')
61
+
62
+ console.log(chalk.green(`\n✅ Manifest created at .launch/app.json`))
63
+ console.log(chalk.gray('\nManifest details:'))
64
+ console.log(chalk.gray(' Type:'), manifest.type)
65
+ console.log(chalk.gray(' Name:'), manifest.name)
66
+ console.log(chalk.gray(' Package:'), manifest.package)
67
+ } catch (error) {
68
+ const message = error instanceof Error ? error.message : String(error)
69
+ console.error(chalk.red('Error:'), message)
70
+ process.exit(1)
71
+ }
72
+ })
73
+
74
+ return command
75
+ }