@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,149 @@
1
+ /**
2
+ * Shared types for the Launch77 catalog system
3
+ */
4
+
5
+ // ============================================================================
6
+ // Catalog File Structure
7
+ // ============================================================================
8
+
9
+ /**
10
+ * UI Component catalog structure
11
+ * Generated by individual component libraries during build
12
+ */
13
+ export interface UiComponentCatalog {
14
+ $schema?: string
15
+ catalogType: 'ui-components'
16
+ catalogVersion: string
17
+ packageName: string
18
+ packageVersion: string
19
+ generatedAt: string
20
+ components: UiComponent[]
21
+ }
22
+
23
+ // ============================================================================
24
+ // Component Metadata
25
+ // ============================================================================
26
+
27
+ /**
28
+ * Complete UI component metadata in catalog
29
+ */
30
+ export interface UiComponent {
31
+ id: string
32
+ kind: 'ui_component'
33
+ name: string
34
+ packageName: string
35
+ category: string
36
+ description: string
37
+ tags: string[]
38
+ props?: string[]
39
+ sourcePath?: string
40
+ library?: string
41
+ guidance?: ComponentGuidance
42
+ example?: string
43
+ examples?: ComponentExamples
44
+ }
45
+
46
+ /**
47
+ * Component usage guidance
48
+ */
49
+ export interface ComponentGuidance {
50
+ whenToUse: string
51
+ whenNotToUse: string
52
+ }
53
+
54
+ /**
55
+ * Component examples reference
56
+ */
57
+ export interface ComponentExamples {
58
+ module: string
59
+ export: string
60
+ sourcePath: string
61
+ }
62
+
63
+ /**
64
+ * Component metadata extracted from JSDoc
65
+ */
66
+ export interface ComponentMetadata {
67
+ description: string
68
+ category: string
69
+ whenToUse: string
70
+ whenNotToUse: string
71
+ tags: string[]
72
+ example: string
73
+ ignored: boolean
74
+ ignoreReason?: string
75
+ }
76
+
77
+ // ============================================================================
78
+ // Validation
79
+ // ============================================================================
80
+
81
+ /**
82
+ * Validation result for a single component
83
+ */
84
+ export interface ValidationResult {
85
+ valid: boolean
86
+ errors: string[]
87
+ warnings: string[]
88
+ componentName: string
89
+ filePath: string
90
+ }
91
+
92
+ /**
93
+ * Quality report for catalog generation
94
+ */
95
+ export interface QualityReport {
96
+ totalComponents: number
97
+ withMetadata: number
98
+ missingMetadata: number
99
+ excluded: number
100
+ errors: ValidationResult[]
101
+ warnings: ValidationResult[]
102
+ qualityScore: number
103
+ }
104
+
105
+ // ============================================================================
106
+ // Configuration
107
+ // ============================================================================
108
+
109
+ /**
110
+ * Catalog generation configuration
111
+ */
112
+ export interface CatalogConfig {
113
+ type: 'ui-components'
114
+ packageName: string
115
+ sourceDir: string
116
+ componentsDir: string
117
+ exportsFile: string
118
+ outputFile: string
119
+ catalogVersion: string
120
+ validation: ValidationConfig
121
+ }
122
+
123
+ /**
124
+ * Validation rules configuration
125
+ */
126
+ export interface ValidationConfig {
127
+ strict: boolean
128
+ requireCategory: boolean
129
+ requireDescription: boolean
130
+ minDescriptionLength: number
131
+ requireWhenToUse: boolean
132
+ requireWhenNotToUse: boolean
133
+ minTags: number
134
+ }
135
+
136
+ // ============================================================================
137
+ // Generation Results
138
+ // ============================================================================
139
+
140
+ /**
141
+ * Result of catalog generation
142
+ */
143
+ export interface GenerationResult {
144
+ success: boolean
145
+ catalogFile: string
146
+ qualityReport: QualityReport
147
+ errors: ValidationResult[]
148
+ warnings: ValidationResult[]
149
+ }
@@ -0,0 +1,68 @@
1
+ import * as path from 'path'
2
+
3
+ import fs from 'fs-extra'
4
+
5
+ import type { UiComponent } from '../types/catalog-types.js'
6
+
7
+ /**
8
+ * Generate examples.generated.ts files for each library that has components with examples
9
+ */
10
+ export async function generateExamplesFiles(components: UiComponent[], launch77Root: string): Promise<void> {
11
+ // Group components by package
12
+ const componentsByPackage = new Map<string, UiComponent[]>()
13
+
14
+ for (const component of components) {
15
+ if (component.examples) {
16
+ const existing = componentsByPackage.get(component.packageName) || []
17
+ existing.push(component)
18
+ componentsByPackage.set(component.packageName, existing)
19
+ }
20
+ }
21
+
22
+ // Generate examples file for each package
23
+ for (const [packageName, packageComponents] of componentsByPackage) {
24
+ // Determine library path based on package name
25
+ // Extract library name from scoped package (e.g., @launch77/ui -> ui)
26
+ const libraryName = packageName.split('/').pop() || packageName
27
+ const libraryPath = path.join(launch77Root, 'libraries', libraryName)
28
+ const examplesFilePath = path.join(libraryPath, 'src', 'examples.generated.ts')
29
+
30
+ // Generate content
31
+ const content = generateExamplesContent(packageComponents, libraryName)
32
+
33
+ // Write file
34
+ await fs.writeFile(examplesFilePath, content, 'utf-8')
35
+
36
+ console.log(` ✓ Generated ${packageName}/examples`)
37
+ }
38
+ }
39
+
40
+ function generateExamplesContent(components: UiComponent[], _libraryName: string): string {
41
+ const lines: string[] = ['// AUTO-GENERATED by launch77 scan - DO NOT EDIT', "// This file is automatically generated when running 'launch77 scan'", '// To add new examples, create a ComponentName.examples.tsx file next to your component', '']
42
+
43
+ // Sort components alphabetically for deterministic output
44
+ const sortedComponents = [...components].sort((a, b) => a.name.localeCompare(b.name))
45
+
46
+ // Add export statements
47
+ for (const component of sortedComponents) {
48
+ if (component.examples && component.examples.sourcePath) {
49
+ // Extract relative path from sourcePath
50
+ // e.g., "launch77/libraries/ui/src/components/Button/Button.examples.tsx"
51
+ // becomes "./components/Button/Button.examples"
52
+ const sourcePath = component.examples.sourcePath
53
+ const srcIndex = sourcePath.indexOf('/src/')
54
+ if (srcIndex !== -1) {
55
+ const relativePath = sourcePath
56
+ .substring(srcIndex + 5) // Skip "/src/"
57
+ .replace(/\.tsx$/, '') // Remove extension
58
+
59
+ // Export structured examples using ComponentNameExamples convention
60
+ // e.g., Button -> ButtonExamples, CTAButton -> CTAButtonExamples
61
+ const structuredExportName = `${component.name}Examples`
62
+ lines.push(`export { ${structuredExportName} } from './${relativePath}'`)
63
+ }
64
+ }
65
+ }
66
+
67
+ return lines.join('\n') + '\n'
68
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Generate and display catalog quality reports
3
+ */
4
+
5
+ import chalk from 'chalk'
6
+
7
+ import type { ValidationResult, QualityReport } from '../types/catalog-types.js'
8
+
9
+ /**
10
+ * Generate quality report from validation results
11
+ */
12
+ export function generateQualityReport(totalScanned: number, excluded: number, validations: ValidationResult[]): QualityReport {
13
+ const errors = validations.filter((v) => !v.valid)
14
+ const withMetadata = validations.filter((v) => v.valid)
15
+
16
+ const qualityScore = totalScanned > 0 ? Math.round((withMetadata.length / totalScanned) * 100) : 100
17
+
18
+ return {
19
+ totalComponents: totalScanned,
20
+ withMetadata: withMetadata.length,
21
+ missingMetadata: errors.length,
22
+ excluded,
23
+ errors,
24
+ warnings: validations.filter((v) => v.warnings.length > 0),
25
+ qualityScore,
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Print quality report to console
31
+ */
32
+ export function printQualityReport(report: QualityReport, strict: boolean): void {
33
+ console.log(chalk.blue('\n📊 Catalog Quality Report\n'))
34
+ console.log(chalk.gray(` Total components scanned: ${report.totalComponents}`))
35
+ console.log(chalk.green(` ✓ With metadata: ${report.withMetadata} (${report.qualityScore}%)`))
36
+
37
+ if (report.missingMetadata > 0) {
38
+ console.log(chalk.red(` ✗ Missing metadata: ${report.missingMetadata}`))
39
+ }
40
+
41
+ if (report.excluded > 0) {
42
+ console.log(chalk.gray(` ℹ Excluded: ${report.excluded}`))
43
+ }
44
+
45
+ // Show errors
46
+ if (report.errors.length > 0) {
47
+ console.log(chalk.red('\n ❌ Components missing metadata:\n'))
48
+ report.errors.forEach((err) => {
49
+ console.log(chalk.red(` - ${err.componentName}`))
50
+ console.log(chalk.gray(` ${err.filePath}`))
51
+ err.errors.forEach((e) => console.log(chalk.gray(` • ${e}`)))
52
+ })
53
+ }
54
+
55
+ // Show warnings (limit to 5)
56
+ if (report.warnings.length > 0 && !strict) {
57
+ console.log(chalk.yellow('\n ⚠️ Metadata warnings:\n'))
58
+ report.warnings.slice(0, 5).forEach((warn) => {
59
+ console.log(chalk.yellow(` - ${warn.componentName}`))
60
+ warn.warnings.forEach((w) => console.log(chalk.gray(` • ${w}`)))
61
+ })
62
+ if (report.warnings.length > 5) {
63
+ console.log(chalk.gray(`\n ... and ${report.warnings.length - 5} more`))
64
+ }
65
+ }
66
+
67
+ console.log()
68
+
69
+ // Help message if there are errors
70
+ if (report.errors.length > 0) {
71
+ console.log(chalk.blue('💡 To fix:\n'))
72
+ console.log(chalk.gray(' • Add @launch77-component JSDoc to public components'))
73
+ console.log(chalk.gray(' • Add @launch77-ignore to exclude internal components'))
74
+ console.log(chalk.gray(' • See: launch77/docs/CATALOG_METADATA_GUIDE.md\n'))
75
+ }
76
+ }
@@ -0,0 +1,233 @@
1
+ import { describe, test, expect } from 'vitest'
2
+
3
+ import { validateComponentName } from './component-name-validator.js'
4
+
5
+ describe('validateComponentName', () => {
6
+ describe('valid names', () => {
7
+ test('single word PascalCase', () => {
8
+ expect(validateComponentName('Button').valid).toBe(true)
9
+ expect(validateComponentName('Alert').valid).toBe(true)
10
+ expect(validateComponentName('Input').valid).toBe(true)
11
+ })
12
+
13
+ test('multi-word PascalCase', () => {
14
+ expect(validateComponentName('AlertDialog').valid).toBe(true)
15
+ expect(validateComponentName('FormField').valid).toBe(true)
16
+ expect(validateComponentName('NavigationMenu').valid).toBe(true)
17
+ })
18
+
19
+ test('with numbers', () => {
20
+ expect(validateComponentName('Button2').valid).toBe(true)
21
+ expect(validateComponentName('Alert3D').valid).toBe(true)
22
+ expect(validateComponentName('H1').valid).toBe(true)
23
+ expect(validateComponentName('Input123').valid).toBe(true)
24
+ })
25
+
26
+ test('common abbreviations', () => {
27
+ expect(validateComponentName('HTTPClient').valid).toBe(true)
28
+ expect(validateComponentName('URLInput').valid).toBe(true)
29
+ expect(validateComponentName('APIKey').valid).toBe(true)
30
+ })
31
+
32
+ test('long valid names', () => {
33
+ const name50 = 'A'.repeat(50)
34
+ expect(validateComponentName(name50).valid).toBe(true)
35
+ })
36
+ })
37
+
38
+ describe('invalid names - symbols and special characters', () => {
39
+ test('special symbols', () => {
40
+ const result1 = validateComponentName('===')
41
+ expect(result1.valid).toBe(false)
42
+ expect(result1.errors[0]).toContain('PascalCase')
43
+
44
+ const result2 = validateComponentName('!!!')
45
+ expect(result2.valid).toBe(false)
46
+
47
+ const result3 = validateComponentName('@@@')
48
+ expect(result3.valid).toBe(false)
49
+ })
50
+
51
+ test('with special characters', () => {
52
+ const result1 = validateComponentName('Button$')
53
+ expect(result1.valid).toBe(false)
54
+ expect(result1.errors[0]).toContain('PascalCase')
55
+
56
+ const result2 = validateComponentName('Alert#Icon')
57
+ expect(result2.valid).toBe(false)
58
+
59
+ const result3 = validateComponentName('Form_Field')
60
+ expect(result3.valid).toBe(false)
61
+ })
62
+
63
+ test('with hyphens', () => {
64
+ const result = validateComponentName('Alert-Dialog')
65
+ expect(result.valid).toBe(false)
66
+ expect(result.errors[0]).toContain('PascalCase')
67
+ })
68
+
69
+ test('with spaces', () => {
70
+ const result1 = validateComponentName('My Button')
71
+ expect(result1.valid).toBe(false)
72
+
73
+ const result2 = validateComponentName('Alert Dialog')
74
+ expect(result2.valid).toBe(false)
75
+
76
+ const result3 = validateComponentName(' Button')
77
+ expect(result3.valid).toBe(false)
78
+ })
79
+
80
+ test('with dots', () => {
81
+ const result = validateComponentName('Button.Icon')
82
+ expect(result.valid).toBe(false)
83
+ expect(result.errors[0]).toContain('PascalCase')
84
+ })
85
+ })
86
+
87
+ describe('invalid names - casing', () => {
88
+ test('lowercase', () => {
89
+ const result = validateComponentName('button')
90
+ expect(result.valid).toBe(false)
91
+ expect(result.errors[0]).toContain('PascalCase')
92
+ })
93
+
94
+ test('camelCase', () => {
95
+ const result = validateComponentName('alertDialog')
96
+ expect(result.valid).toBe(false)
97
+ expect(result.errors[0]).toContain('PascalCase')
98
+ })
99
+
100
+ test('snake_case', () => {
101
+ const result = validateComponentName('alert_dialog')
102
+ expect(result.valid).toBe(false)
103
+ expect(result.errors[0]).toContain('PascalCase')
104
+ })
105
+
106
+ test('SCREAMING_SNAKE_CASE', () => {
107
+ const result = validateComponentName('ALERT_DIALOG')
108
+ expect(result.valid).toBe(false)
109
+ expect(result.errors[0]).toContain('PascalCase')
110
+ })
111
+
112
+ test('kebab-case', () => {
113
+ const result = validateComponentName('alert-dialog')
114
+ expect(result.valid).toBe(false)
115
+ expect(result.errors[0]).toContain('PascalCase')
116
+ })
117
+ })
118
+
119
+ describe('invalid names - numbers', () => {
120
+ test('only numbers', () => {
121
+ const result = validateComponentName('123')
122
+ expect(result.valid).toBe(false)
123
+ expect(result.errors[0]).toContain('PascalCase')
124
+ })
125
+
126
+ test('starting with number', () => {
127
+ const result = validateComponentName('3DButton')
128
+ expect(result.valid).toBe(false)
129
+ expect(result.errors[0]).toContain('PascalCase')
130
+ })
131
+ })
132
+
133
+ describe('invalid names - empty and length', () => {
134
+ test('empty string', () => {
135
+ const result = validateComponentName('')
136
+ expect(result.valid).toBe(false)
137
+ expect(result.errors[0]).toContain('cannot be empty')
138
+ })
139
+
140
+ test('exceeds maximum length', () => {
141
+ const name51 = 'A'.repeat(51)
142
+ const result = validateComponentName(name51)
143
+ expect(result.valid).toBe(false)
144
+ expect(result.errors[0]).toContain('maximum length')
145
+ expect(result.errors[0]).toContain('50')
146
+ })
147
+
148
+ test('very long name', () => {
149
+ const name100 = 'A'.repeat(100)
150
+ const result = validateComponentName(name100)
151
+ expect(result.valid).toBe(false)
152
+ expect(result.errors[0]).toContain('maximum length')
153
+ })
154
+ })
155
+
156
+ describe('multiple errors', () => {
157
+ test('empty string has one error', () => {
158
+ const result = validateComponentName('')
159
+ expect(result.errors.length).toBeGreaterThan(0)
160
+ })
161
+
162
+ test('lowercase name has error', () => {
163
+ const result = validateComponentName('button')
164
+ expect(result.errors.length).toBeGreaterThanOrEqual(1)
165
+ expect(result.errors[0]).toContain('PascalCase')
166
+ })
167
+
168
+ test('symbol-only name has error', () => {
169
+ const result = validateComponentName('$$$')
170
+ expect(result.valid).toBe(false)
171
+ expect(result.errors.length).toBeGreaterThan(0)
172
+ })
173
+ })
174
+
175
+ describe('edge cases', () => {
176
+ test('single letter uppercase', () => {
177
+ expect(validateComponentName('A').valid).toBe(true)
178
+ expect(validateComponentName('Z').valid).toBe(true)
179
+ })
180
+
181
+ test('exactly 50 characters', () => {
182
+ const name = 'A'.repeat(50)
183
+ expect(validateComponentName(name).valid).toBe(true)
184
+ })
185
+
186
+ test('51 characters', () => {
187
+ const name = 'A'.repeat(51)
188
+ expect(validateComponentName(name).valid).toBe(false)
189
+ })
190
+
191
+ test('unicode characters', () => {
192
+ const result = validateComponentName('Buttoné')
193
+ expect(result.valid).toBe(false)
194
+ expect(result.errors[0]).toContain('PascalCase')
195
+ })
196
+
197
+ test('emoji', () => {
198
+ const result = validateComponentName('Button😀')
199
+ expect(result.valid).toBe(false)
200
+ expect(result.errors[0]).toContain('PascalCase')
201
+ })
202
+ })
203
+
204
+ describe('common real-world component names', () => {
205
+ test('UI library components', () => {
206
+ expect(validateComponentName('Dialog').valid).toBe(true)
207
+ expect(validateComponentName('Popover').valid).toBe(true)
208
+ expect(validateComponentName('Tooltip').valid).toBe(true)
209
+ expect(validateComponentName('Select').valid).toBe(true)
210
+ expect(validateComponentName('Checkbox').valid).toBe(true)
211
+ expect(validateComponentName('RadioGroup').valid).toBe(true)
212
+ expect(validateComponentName('Accordion').valid).toBe(true)
213
+ expect(validateComponentName('Tabs').valid).toBe(true)
214
+ expect(validateComponentName('Card').valid).toBe(true)
215
+ expect(validateComponentName('Badge').valid).toBe(true)
216
+ })
217
+
218
+ test('form components', () => {
219
+ expect(validateComponentName('FormField').valid).toBe(true)
220
+ expect(validateComponentName('FormError').valid).toBe(true)
221
+ expect(validateComponentName('FormHelperText').valid).toBe(true)
222
+ expect(validateComponentName('TextField').valid).toBe(true)
223
+ expect(validateComponentName('TextArea').valid).toBe(true)
224
+ })
225
+
226
+ test('navigation components', () => {
227
+ expect(validateComponentName('Navbar').valid).toBe(true)
228
+ expect(validateComponentName('Sidebar').valid).toBe(true)
229
+ expect(validateComponentName('Breadcrumbs').valid).toBe(true)
230
+ expect(validateComponentName('NavigationMenu').valid).toBe(true)
231
+ })
232
+ })
233
+ })
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Validate component names for Launch77 catalog
3
+ */
4
+
5
+ const VALID_COMPONENT_NAME = /^[A-Z][a-zA-Z0-9]*$/
6
+ const MAX_COMPONENT_NAME_LENGTH = 50
7
+
8
+ export interface ComponentNameValidation {
9
+ valid: boolean
10
+ errors: string[]
11
+ }
12
+
13
+ /**
14
+ * Validate a component name against Launch77 naming conventions
15
+ *
16
+ * Rules:
17
+ * - Must start with uppercase letter (A-Z)
18
+ * - Only alphanumeric characters (no symbols, spaces, or special characters)
19
+ * - Maximum 50 characters
20
+ *
21
+ * @param name - Component name to validate
22
+ * @returns Validation result with errors if invalid
23
+ */
24
+ export function validateComponentName(name: string): ComponentNameValidation {
25
+ const errors: string[] = []
26
+
27
+ if (!name || name.length === 0) {
28
+ errors.push('Component name cannot be empty')
29
+ }
30
+
31
+ if (name.length > MAX_COMPONENT_NAME_LENGTH) {
32
+ errors.push(`Component name exceeds maximum length of ${MAX_COMPONENT_NAME_LENGTH} characters`)
33
+ }
34
+
35
+ if (!VALID_COMPONENT_NAME.test(name)) {
36
+ errors.push('Component name must be PascalCase (start with uppercase letter A-Z, alphanumeric only)')
37
+ }
38
+
39
+ return {
40
+ valid: errors.length === 0,
41
+ errors,
42
+ }
43
+ }