@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,404 @@
1
+ import { describe, test, expect } from 'vitest'
2
+
3
+ import { validateConfig, getDefaultConfig } from './catalog-config.js'
4
+
5
+ describe('validateConfig', () => {
6
+ describe('valid configurations', () => {
7
+ test('minimal valid config', () => {
8
+ const config = {
9
+ type: 'ui-components',
10
+ packageName: '@launch77/ui',
11
+ }
12
+ const result = validateConfig(config)
13
+ expect(result.type).toBe('ui-components')
14
+ expect(result.packageName).toBe('@launch77/ui')
15
+ })
16
+
17
+ test('full valid config', () => {
18
+ const config = {
19
+ type: 'ui-components',
20
+ packageName: '@launch77/ui',
21
+ sourceDir: './src',
22
+ componentsDir: './src/components',
23
+ exportsFile: './src/index.ts',
24
+ outputFile: 'catalog-ui-components.json',
25
+ catalogVersion: '0.1.0',
26
+ validation: {
27
+ strict: true,
28
+ requireCategory: true,
29
+ requireDescription: true,
30
+ minDescriptionLength: 20,
31
+ requireWhenToUse: true,
32
+ requireWhenNotToUse: true,
33
+ minTags: 3,
34
+ },
35
+ }
36
+ const result = validateConfig(config)
37
+ expect(result).toEqual(config)
38
+ })
39
+
40
+ test('various valid package names', () => {
41
+ expect(validateConfig({ type: 'ui-components', packageName: '@launch77/ui' })).toBeTruthy()
42
+ expect(validateConfig({ type: 'ui-components', packageName: '@my-company/components' })).toBeTruthy()
43
+ expect(validateConfig({ type: 'ui-components', packageName: '@org/lib' })).toBeTruthy()
44
+ expect(validateConfig({ type: 'ui-components', packageName: '@abc123/xyz789' })).toBeTruthy()
45
+ })
46
+
47
+ test('various valid catalog versions', () => {
48
+ expect(
49
+ validateConfig({
50
+ type: 'ui-components',
51
+ packageName: '@launch77/ui',
52
+ catalogVersion: '0.1.0',
53
+ })
54
+ ).toBeTruthy()
55
+ expect(
56
+ validateConfig({
57
+ type: 'ui-components',
58
+ packageName: '@launch77/ui',
59
+ catalogVersion: '1.0.0',
60
+ })
61
+ ).toBeTruthy()
62
+ expect(
63
+ validateConfig({
64
+ type: 'ui-components',
65
+ packageName: '@launch77/ui',
66
+ catalogVersion: '12.34.56',
67
+ })
68
+ ).toBeTruthy()
69
+ })
70
+ })
71
+
72
+ describe('defaults applied', () => {
73
+ test('applies default sourceDir', () => {
74
+ const config = {
75
+ type: 'ui-components',
76
+ packageName: '@launch77/ui',
77
+ }
78
+ const result = validateConfig(config)
79
+ expect(result.sourceDir).toBe('./src')
80
+ })
81
+
82
+ test('applies default componentsDir', () => {
83
+ const config = {
84
+ type: 'ui-components',
85
+ packageName: '@launch77/ui',
86
+ }
87
+ const result = validateConfig(config)
88
+ expect(result.componentsDir).toBe('./src/components')
89
+ })
90
+
91
+ test('applies default exportsFile', () => {
92
+ const config = {
93
+ type: 'ui-components',
94
+ packageName: '@launch77/ui',
95
+ }
96
+ const result = validateConfig(config)
97
+ expect(result.exportsFile).toBe('./src/index.ts')
98
+ })
99
+
100
+ test('applies default outputFile', () => {
101
+ const config = {
102
+ type: 'ui-components',
103
+ packageName: '@launch77/ui',
104
+ }
105
+ const result = validateConfig(config)
106
+ expect(result.outputFile).toBe('catalog-ui-components.json')
107
+ })
108
+
109
+ test('applies default catalogVersion', () => {
110
+ const config = {
111
+ type: 'ui-components',
112
+ packageName: '@launch77/ui',
113
+ }
114
+ const result = validateConfig(config)
115
+ expect(result.catalogVersion).toBe('0.1.0')
116
+ })
117
+
118
+ test('applies default validation config', () => {
119
+ const config = {
120
+ type: 'ui-components',
121
+ packageName: '@launch77/ui',
122
+ }
123
+ const result = validateConfig(config)
124
+ expect(result.validation).toEqual({
125
+ strict: true,
126
+ requireCategory: true,
127
+ requireDescription: true,
128
+ minDescriptionLength: 20,
129
+ requireWhenToUse: true,
130
+ requireWhenNotToUse: true,
131
+ minTags: 3,
132
+ })
133
+ })
134
+
135
+ test('partial validation config merges with defaults', () => {
136
+ const config = {
137
+ type: 'ui-components',
138
+ packageName: '@launch77/ui',
139
+ validation: {
140
+ strict: false,
141
+ },
142
+ }
143
+ const result = validateConfig(config)
144
+ expect(result.validation.strict).toBe(false)
145
+ expect(result.validation.requireCategory).toBe(true) // default
146
+ })
147
+ })
148
+
149
+ describe('invalid type', () => {
150
+ test('missing type', () => {
151
+ const config = {
152
+ packageName: '@launch77/ui',
153
+ }
154
+ expect(() => validateConfig(config)).toThrow('Invalid catalog configuration')
155
+ })
156
+
157
+ test('wrong type value', () => {
158
+ const config = {
159
+ type: 'server-functions',
160
+ packageName: '@launch77/ui',
161
+ }
162
+ expect(() => validateConfig(config)).toThrow('Type must be "ui-components"')
163
+ })
164
+
165
+ test('type is number', () => {
166
+ const config = {
167
+ type: 123,
168
+ packageName: '@launch77/ui',
169
+ }
170
+ expect(() => validateConfig(config)).toThrow()
171
+ })
172
+ })
173
+
174
+ describe('invalid packageName', () => {
175
+ test('missing packageName', () => {
176
+ const config = {
177
+ type: 'ui-components',
178
+ }
179
+ expect(() => validateConfig(config)).toThrow('Invalid catalog configuration')
180
+ })
181
+
182
+ test('no scope', () => {
183
+ const config = {
184
+ type: 'ui-components',
185
+ packageName: 'ui',
186
+ }
187
+ expect(() => validateConfig(config)).toThrow('Package name must match pattern')
188
+ })
189
+
190
+ test('missing package name after scope', () => {
191
+ const config = {
192
+ type: 'ui-components',
193
+ packageName: '@launch77/',
194
+ }
195
+ expect(() => validateConfig(config)).toThrow('Package name must match pattern')
196
+ })
197
+
198
+ test('uppercase letters', () => {
199
+ const config = {
200
+ type: 'ui-components',
201
+ packageName: '@Launch77/UI',
202
+ }
203
+ expect(() => validateConfig(config)).toThrow('Package name must match pattern')
204
+ })
205
+
206
+ test('spaces', () => {
207
+ const config = {
208
+ type: 'ui-components',
209
+ packageName: '@launch 77/ui',
210
+ }
211
+ expect(() => validateConfig(config)).toThrow('Package name must match pattern')
212
+ })
213
+
214
+ test('special characters', () => {
215
+ const config = {
216
+ type: 'ui-components',
217
+ packageName: '@launch77/ui!',
218
+ }
219
+ expect(() => validateConfig(config)).toThrow('Package name must match pattern')
220
+ })
221
+
222
+ test('multiple slashes', () => {
223
+ const config = {
224
+ type: 'ui-components',
225
+ packageName: '@launch77/ui/components',
226
+ }
227
+ expect(() => validateConfig(config)).toThrow('Package name must match pattern')
228
+ })
229
+ })
230
+
231
+ describe('invalid catalogVersion', () => {
232
+ test('not semantic version', () => {
233
+ const config = {
234
+ type: 'ui-components',
235
+ packageName: '@launch77/ui',
236
+ catalogVersion: 'v1.0',
237
+ }
238
+ expect(() => validateConfig(config)).toThrow('Catalog version must be semantic version')
239
+ })
240
+
241
+ test('with v prefix', () => {
242
+ const config = {
243
+ type: 'ui-components',
244
+ packageName: '@launch77/ui',
245
+ catalogVersion: 'v1.0.0',
246
+ }
247
+ expect(() => validateConfig(config)).toThrow('Catalog version must be semantic version')
248
+ })
249
+
250
+ test('missing patch', () => {
251
+ const config = {
252
+ type: 'ui-components',
253
+ packageName: '@launch77/ui',
254
+ catalogVersion: '1.0',
255
+ }
256
+ expect(() => validateConfig(config)).toThrow('Catalog version must be semantic version')
257
+ })
258
+
259
+ test('extra segments', () => {
260
+ const config = {
261
+ type: 'ui-components',
262
+ packageName: '@launch77/ui',
263
+ catalogVersion: '1.0.0.0',
264
+ }
265
+ expect(() => validateConfig(config)).toThrow('Catalog version must be semantic version')
266
+ })
267
+ })
268
+
269
+ describe('invalid validation config', () => {
270
+ test('strict is not boolean', () => {
271
+ const config = {
272
+ type: 'ui-components',
273
+ packageName: '@launch77/ui',
274
+ validation: {
275
+ strict: 'yes',
276
+ },
277
+ }
278
+ expect(() => validateConfig(config)).toThrow()
279
+ })
280
+
281
+ test('negative minDescriptionLength', () => {
282
+ const config = {
283
+ type: 'ui-components',
284
+ packageName: '@launch77/ui',
285
+ validation: {
286
+ minDescriptionLength: -1,
287
+ },
288
+ }
289
+ expect(() => validateConfig(config)).toThrow()
290
+ })
291
+
292
+ test('negative minTags', () => {
293
+ const config = {
294
+ type: 'ui-components',
295
+ packageName: '@launch77/ui',
296
+ validation: {
297
+ minTags: -5,
298
+ },
299
+ }
300
+ expect(() => validateConfig(config)).toThrow()
301
+ })
302
+ })
303
+
304
+ describe('error messages', () => {
305
+ test('provides clear field name in error', () => {
306
+ const config = {
307
+ type: 'ui-components',
308
+ packageName: 'invalid',
309
+ }
310
+ try {
311
+ validateConfig(config)
312
+ expect(true).toBe(false) // Should not reach here
313
+ } catch (error) {
314
+ expect((error as Error).message).toContain('packageName')
315
+ }
316
+ })
317
+
318
+ test('provides helpful message for invalid type', () => {
319
+ const config = {
320
+ type: 'wrong',
321
+ packageName: '@launch77/ui',
322
+ }
323
+ try {
324
+ validateConfig(config)
325
+ expect(true).toBe(false) // Should not reach here
326
+ } catch (error) {
327
+ expect((error as Error).message).toContain('ui-components')
328
+ }
329
+ })
330
+
331
+ test('multiple errors shown together', () => {
332
+ const config = {
333
+ type: 'wrong',
334
+ packageName: 'invalid',
335
+ catalogVersion: 'bad',
336
+ }
337
+ try {
338
+ validateConfig(config)
339
+ expect(true).toBe(false) // Should not reach here
340
+ } catch (error) {
341
+ expect((error as Error).message).toContain('type')
342
+ expect((error as Error).message).toContain('packageName')
343
+ expect((error as Error).message).toContain('catalogVersion')
344
+ }
345
+ })
346
+ })
347
+
348
+ describe('getDefaultConfig', () => {
349
+ test('returns default values', () => {
350
+ const defaults = getDefaultConfig()
351
+ expect(defaults.sourceDir).toBe('./src')
352
+ expect(defaults.componentsDir).toBe('./src/components')
353
+ expect(defaults.exportsFile).toBe('./src/index.ts')
354
+ expect(defaults.outputFile).toBe('catalog-ui-components.json')
355
+ expect(defaults.catalogVersion).toBe('0.1.0')
356
+ })
357
+
358
+ test('returns default validation config', () => {
359
+ const defaults = getDefaultConfig()
360
+ expect(defaults.validation).toEqual({
361
+ strict: true,
362
+ requireCategory: true,
363
+ requireDescription: true,
364
+ minDescriptionLength: 20,
365
+ requireWhenToUse: true,
366
+ requireWhenNotToUse: true,
367
+ minTags: 3,
368
+ })
369
+ })
370
+ })
371
+
372
+ describe('edge cases', () => {
373
+ test('null config', () => {
374
+ expect(() => validateConfig(null)).toThrow()
375
+ })
376
+
377
+ test('undefined config', () => {
378
+ expect(() => validateConfig(undefined)).toThrow()
379
+ })
380
+
381
+ test('empty object', () => {
382
+ expect(() => validateConfig({})).toThrow()
383
+ })
384
+
385
+ test('array instead of object', () => {
386
+ expect(() => validateConfig([])).toThrow()
387
+ })
388
+
389
+ test('string instead of object', () => {
390
+ expect(() => validateConfig('config')).toThrow()
391
+ })
392
+
393
+ test('extra fields are allowed', () => {
394
+ const config = {
395
+ type: 'ui-components',
396
+ packageName: '@launch77/ui',
397
+ extraField: 'ignored',
398
+ }
399
+ const result = validateConfig(config)
400
+ expect(result).toBeTruthy()
401
+ // Extra fields don't cause errors (passthrough mode)
402
+ })
403
+ })
404
+ })
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Configuration system for catalog generation
3
+ */
4
+
5
+ import path from 'path'
6
+ import { pathToFileURL } from 'url'
7
+
8
+ import fs from 'fs-extra'
9
+ import { z } from 'zod'
10
+
11
+ import type { CatalogConfig } from '../types/catalog-types.js'
12
+
13
+ /**
14
+ * Zod schema for catalog configuration
15
+ * Provides runtime validation and type safety
16
+ */
17
+ export const CatalogConfigSchema = z.object({
18
+ type: z.literal('ui-components'),
19
+ packageName: z.string().regex(/^@[a-z0-9-]+\/[a-z0-9-]+$/, 'Package name must match pattern @scope/name (e.g., @launch77/ui)'),
20
+ sourceDir: z.string().default('./src'),
21
+ componentsDir: z.string().default('./src/components'),
22
+ exportsFile: z.string().default('./src/index.ts'),
23
+ outputFile: z.string().default('catalog-ui-components.json'),
24
+ catalogVersion: z
25
+ .string()
26
+ .regex(/^\d+\.\d+\.\d+$/, 'Catalog version must be semantic version (e.g., 0.1.0)')
27
+ .default('0.1.0'),
28
+ validation: z
29
+ .object({
30
+ strict: z.boolean().default(true),
31
+ requireCategory: z.boolean().default(true),
32
+ requireDescription: z.boolean().default(true),
33
+ minDescriptionLength: z.number().min(0).default(20),
34
+ requireWhenToUse: z.boolean().default(true),
35
+ requireWhenNotToUse: z.boolean().default(true),
36
+ minTags: z.number().min(0).default(3),
37
+ })
38
+ .default({
39
+ strict: true,
40
+ requireCategory: true,
41
+ requireDescription: true,
42
+ minDescriptionLength: 20,
43
+ requireWhenToUse: true,
44
+ requireWhenNotToUse: true,
45
+ minTags: 3,
46
+ }),
47
+ })
48
+
49
+ /**
50
+ * Type helper to ensure CatalogConfig matches schema
51
+ */
52
+ type InferredConfig = z.infer<typeof CatalogConfigSchema>
53
+
54
+ // Ensure our type matches the Zod schema
55
+ const _typeCheck: InferredConfig extends CatalogConfig ? true : false = true
56
+ const _typeCheck2: CatalogConfig extends InferredConfig ? true : false = true
57
+
58
+ /**
59
+ * Read catalog configuration from a library directory
60
+ *
61
+ * @param libraryPath - Absolute path to the library directory
62
+ * @returns Validated catalog configuration
63
+ * @throws Error if config file not found or invalid
64
+ */
65
+ export async function readCatalogConfig(libraryPath: string): Promise<CatalogConfig> {
66
+ const configPath = path.join(libraryPath, 'catalog.config.js')
67
+
68
+ if (!(await fs.pathExists(configPath))) {
69
+ throw new Error(`Catalog config file not found: ${configPath}\n\n` + 'Create a catalog.config.js file in your library root with:\n' + 'export default {\n' + ' type: "ui-components",\n' + ' packageName: "@your-scope/your-package",\n' + ' ...\n' + '}')
70
+ }
71
+
72
+ try {
73
+ // Convert to file URL for ES module import
74
+ const fileUrl = pathToFileURL(configPath).href
75
+ const configModule = await import(fileUrl)
76
+ const config = configModule.default || configModule
77
+
78
+ return validateConfig(config)
79
+ } catch (error) {
80
+ if (error instanceof Error && error.message.includes('Cannot find module')) {
81
+ throw new Error(`Failed to import config file: ${configPath}\n${error.message}`)
82
+ }
83
+ throw error
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Validate catalog configuration against schema
89
+ *
90
+ * @param config - Raw configuration object
91
+ * @returns Validated and typed configuration
92
+ * @throws Error with detailed validation errors if invalid
93
+ */
94
+ export function validateConfig(config: unknown): CatalogConfig {
95
+ try {
96
+ return CatalogConfigSchema.parse(config)
97
+ } catch (error) {
98
+ if (error instanceof z.ZodError) {
99
+ const messages = error.issues.map((issue) => {
100
+ const field = issue.path.join('.')
101
+ return ` - ${field}: ${issue.message}`
102
+ })
103
+ throw new Error(`Invalid catalog configuration:\n\n${messages.join('\n')}\n`)
104
+ }
105
+ throw error
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Get default configuration values
111
+ * Useful for documentation and testing
112
+ */
113
+ export function getDefaultConfig(): Partial<CatalogConfig> {
114
+ return {
115
+ sourceDir: './src',
116
+ componentsDir: './src/components',
117
+ exportsFile: './src/index.ts',
118
+ outputFile: 'catalog-ui-components.json',
119
+ catalogVersion: '0.1.0',
120
+ validation: {
121
+ strict: true,
122
+ requireCategory: true,
123
+ requireDescription: true,
124
+ minDescriptionLength: 20,
125
+ requireWhenToUse: true,
126
+ requireWhenNotToUse: true,
127
+ minTags: 3,
128
+ },
129
+ }
130
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Catalog Module
3
+ *
4
+ * Scans Launch77 artifacts and generates catalog.json for AI discovery
5
+ */
6
+
7
+ export * from './commands/scan.js'
8
+ export * from './commands/generate.js'
9
+ export * from './services/catalog-svc.js'
@@ -0,0 +1,93 @@
1
+ import * as path from 'path'
2
+
3
+ import fs from 'fs-extra'
4
+ import * as ts from 'typescript'
5
+
6
+ export interface PropInfo {
7
+ name: string
8
+ type?: string
9
+ required?: boolean
10
+ }
11
+
12
+ /**
13
+ * Extract prop names from a React component TypeScript file
14
+ * Looks for Props interfaces/types and exports
15
+ */
16
+ export async function extractProps(filePath: string): Promise<string[]> {
17
+ try {
18
+ const content = await fs.readFile(filePath, 'utf-8')
19
+ const sourceFile = ts.createSourceFile(path.basename(filePath), content, ts.ScriptTarget.Latest, true)
20
+
21
+ const props: Set<string> = new Set()
22
+
23
+ // Visit all nodes in the AST
24
+ const visitor = (node: ts.Node): void => {
25
+ // Look for type/interface definitions with "Props" in the name
26
+ if (ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node)) {
27
+ const name = node.name.text
28
+ if (name.includes('Props')) {
29
+ extractPropsFromType(node, props)
30
+ }
31
+ }
32
+
33
+ ts.forEachChild(node, visitor)
34
+ }
35
+
36
+ visitor(sourceFile)
37
+
38
+ return Array.from(props)
39
+ } catch (error) {
40
+ // If parsing fails, return empty array
41
+ return []
42
+ }
43
+ }
44
+
45
+ function extractPropsFromType(node: ts.InterfaceDeclaration | ts.TypeAliasDeclaration, props: Set<string>) {
46
+ if (ts.isInterfaceDeclaration(node)) {
47
+ // Extract from interface members
48
+ node.members.forEach((member) => {
49
+ if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
50
+ props.add(member.name.text)
51
+ }
52
+ })
53
+ } else if (ts.isTypeAliasDeclaration(node)) {
54
+ // Extract from type alias
55
+ const typeNode = node.type
56
+ if (ts.isIntersectionTypeNode(typeNode)) {
57
+ // Handle intersection types (e.g., A & B & C)
58
+ typeNode.types.forEach((type) => {
59
+ if (ts.isTypeLiteralNode(type)) {
60
+ type.members.forEach((member) => {
61
+ if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
62
+ props.add(member.name.text)
63
+ }
64
+ })
65
+ }
66
+ })
67
+ } else if (ts.isTypeLiteralNode(typeNode)) {
68
+ // Handle type literal (e.g., { prop1: string })
69
+ typeNode.members.forEach((member) => {
70
+ if (ts.isPropertySignature(member) && member.name && ts.isIdentifier(member.name)) {
71
+ props.add(member.name.text)
72
+ }
73
+ })
74
+ }
75
+ }
76
+
77
+ // Add common HTML attributes that are usually inherited
78
+ const commonProps = ['className', 'style', 'children', 'onClick', 'onChange']
79
+ commonProps.forEach((prop) => props.add(prop))
80
+ }
81
+
82
+ /**
83
+ * Detect if a file is a React component
84
+ */
85
+ export async function isReactComponent(filePath: string): Promise<boolean> {
86
+ try {
87
+ const content = await fs.readFile(filePath, 'utf-8')
88
+ // Simple heuristic: contains React import and JSX/TSX
89
+ return content.includes('import') && (content.includes('React') || content.includes("from 'react'")) && (filePath.endsWith('.tsx') || filePath.endsWith('.jsx'))
90
+ } catch {
91
+ return false
92
+ }
93
+ }