parseArgs.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. // Parse plugin subcommand arguments into structured commands
  2. export type ParsedCommand =
  3. | { type: 'menu' }
  4. | { type: 'help' }
  5. | { type: 'install'; marketplace?: string; plugin?: string }
  6. | { type: 'manage' }
  7. | { type: 'uninstall'; plugin?: string }
  8. | { type: 'enable'; plugin?: string }
  9. | { type: 'disable'; plugin?: string }
  10. | { type: 'validate'; path?: string }
  11. | {
  12. type: 'marketplace'
  13. action?: 'add' | 'remove' | 'update' | 'list'
  14. target?: string
  15. }
  16. export function parsePluginArgs(args?: string): ParsedCommand {
  17. if (!args) {
  18. return { type: 'menu' }
  19. }
  20. const parts = args.trim().split(/\s+/)
  21. const command = parts[0]?.toLowerCase()
  22. switch (command) {
  23. case 'help':
  24. case '--help':
  25. case '-h':
  26. return { type: 'help' }
  27. case 'install':
  28. case 'i': {
  29. const target = parts[1]
  30. if (!target) {
  31. return { type: 'install' }
  32. }
  33. // Check if it's in format plugin@marketplace
  34. if (target.includes('@')) {
  35. const [plugin, marketplace] = target.split('@')
  36. return { type: 'install', plugin, marketplace }
  37. }
  38. // Check if the target looks like a marketplace (URL or path)
  39. const isMarketplace =
  40. target.startsWith('http://') ||
  41. target.startsWith('https://') ||
  42. target.startsWith('file://') ||
  43. target.includes('/') ||
  44. target.includes('\\')
  45. if (isMarketplace) {
  46. // This is a marketplace URL/path, no plugin specified
  47. return { type: 'install', marketplace: target }
  48. }
  49. // Otherwise treat it as a plugin name
  50. return { type: 'install', plugin: target }
  51. }
  52. case 'manage':
  53. return { type: 'manage' }
  54. case 'uninstall':
  55. return { type: 'uninstall', plugin: parts[1] }
  56. case 'enable':
  57. return { type: 'enable', plugin: parts[1] }
  58. case 'disable':
  59. return { type: 'disable', plugin: parts[1] }
  60. case 'validate': {
  61. const target = parts.slice(1).join(' ').trim()
  62. return { type: 'validate', path: target || undefined }
  63. }
  64. case 'marketplace':
  65. case 'market': {
  66. const action = parts[1]?.toLowerCase()
  67. const target = parts.slice(2).join(' ')
  68. switch (action) {
  69. case 'add':
  70. return { type: 'marketplace', action: 'add', target }
  71. case 'remove':
  72. case 'rm':
  73. return { type: 'marketplace', action: 'remove', target }
  74. case 'update':
  75. return { type: 'marketplace', action: 'update', target }
  76. case 'list':
  77. return { type: 'marketplace', action: 'list' }
  78. default:
  79. // No action specified, show marketplace menu
  80. return { type: 'marketplace' }
  81. }
  82. }
  83. default:
  84. // Unknown command, show menu
  85. return { type: 'menu' }
  86. }
  87. }