index.ts 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/env -S npx tsx@latest
  2. import inquirer from 'inquirer';
  3. import { Command } from 'commander';
  4. import chalk from 'chalk';
  5. import { getProjectInfo, installDependencies, ProjectInfo } from './project.js';
  6. import { bfsMaterials, copyMaterial, listAllMaterials, Material } from './materials.js';
  7. const program = new Command();
  8. program
  9. .version('1.0.1')
  10. .description('Add official materials to your project')
  11. .argument('[materialName]', 'Optional material name to skip selection (format: type/name)')
  12. .action(async (materialName?: string) => {
  13. // materialName can be undefined
  14. console.log(chalk.bgGreenBright('Welcome to @flowgram.ai/form-materials CLI!'));
  15. const projectInfo: ProjectInfo = getProjectInfo();
  16. console.log(chalk.bold('Project Info:'));
  17. console.log(chalk.black(` - Flowgram Version: ${projectInfo.flowgramVersion}`));
  18. console.log(chalk.black(` - Project Path: ${projectInfo.projectPath}`));
  19. const materials: Material[] = listAllMaterials();
  20. let material: Material | undefined; // material can be undefined
  21. // Check if materialName is provided and exists in materials
  22. if (materialName) {
  23. const selectedMaterial = materials.find((m) => `${m.type}/${m.name}` === materialName);
  24. if (selectedMaterial) {
  25. material = selectedMaterial;
  26. console.log(chalk.green(`Using material: ${materialName}`));
  27. } else {
  28. console.log(
  29. chalk.yellow(`Material "${materialName}" not found. Please select from the list:`)
  30. );
  31. }
  32. }
  33. // If material not found or materialName not provided, prompt user to select
  34. if (!material) {
  35. // User select one component
  36. const result = await inquirer.prompt<{
  37. material: Material; // Specify type for prompt result
  38. }>([
  39. {
  40. type: 'list',
  41. name: 'material',
  42. message: 'Select one material to add:',
  43. choices: [
  44. ...materials.map((_material) => ({
  45. name: `${_material.type}/${_material.name}`,
  46. value: _material,
  47. })),
  48. ],
  49. },
  50. ]);
  51. material = result.material;
  52. }
  53. // Ensure material is defined before proceeding
  54. if (!material) {
  55. console.error(chalk.red('No material selected. Exiting.'));
  56. process.exit(1);
  57. }
  58. console.log(material);
  59. // 3. Get the component dependencies by BFS (include depMaterials and depPackages)
  60. const { allMaterials, allPackages } = bfsMaterials(material!, materials);
  61. // 4. Install the dependencies
  62. allPackages.push(`@flowgram.ai/editor`);
  63. const packagesToInstall: string[] = allPackages.map((_pkg) => {
  64. if (
  65. _pkg.startsWith(`@flowgram.ai/`) &&
  66. projectInfo.flowgramVersion !== 'workspace:*' &&
  67. !_pkg.endsWith(`@${projectInfo.flowgramVersion}`)
  68. ) {
  69. return `${_pkg}@${projectInfo.flowgramVersion}`;
  70. }
  71. return _pkg;
  72. });
  73. console.log(chalk.bold('These npm dependencies will be added to your project'));
  74. console.log(packagesToInstall);
  75. installDependencies(packagesToInstall, projectInfo);
  76. // 5. Copy the materials to the project
  77. console.log(chalk.bold('These Materials will be added to your project'));
  78. console.log(allMaterials);
  79. copyMaterial(material, projectInfo, { overwrite: true });
  80. allMaterials.forEach((mat: Material) => {
  81. if (mat === material) {
  82. return;
  83. }
  84. // Add type for mat
  85. copyMaterial(mat, projectInfo, { overwrite: false });
  86. });
  87. });
  88. program.parse(process.argv);