@villedemontreal/caporal 3.1.7

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 (425) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +29 -0
  3. package/dist/src/__tests__/issue-163.spec.d.ts +2 -0
  4. package/dist/src/__tests__/issue-163.spec.d.ts.map +1 -0
  5. package/dist/src/__tests__/issue-163.spec.js +17 -0
  6. package/dist/src/__tests__/issue-163.spec.js.map +1 -0
  7. package/dist/src/argument/__tests__/argument.spec.d.ts +2 -0
  8. package/dist/src/argument/__tests__/argument.spec.d.ts.map +1 -0
  9. package/dist/src/argument/__tests__/argument.spec.js +85 -0
  10. package/dist/src/argument/__tests__/argument.spec.js.map +1 -0
  11. package/dist/src/argument/find.d.ts +8 -0
  12. package/dist/src/argument/find.d.ts.map +1 -0
  13. package/dist/src/argument/find.js +11 -0
  14. package/dist/src/argument/find.js.map +1 -0
  15. package/dist/src/argument/index.d.ts +13 -0
  16. package/dist/src/argument/index.d.ts.map +1 -0
  17. package/dist/src/argument/index.js +27 -0
  18. package/dist/src/argument/index.js.map +1 -0
  19. package/dist/src/argument/synopsis.d.ts +19 -0
  20. package/dist/src/argument/synopsis.d.ts.map +1 -0
  21. package/dist/src/argument/synopsis.js +39 -0
  22. package/dist/src/argument/synopsis.js.map +1 -0
  23. package/dist/src/argument/validate.d.ts +43 -0
  24. package/dist/src/argument/validate.d.ts.map +1 -0
  25. package/dist/src/argument/validate.js +127 -0
  26. package/dist/src/argument/validate.js.map +1 -0
  27. package/dist/src/autocomplete/__fixtures__/prog-autocomplete.d.ts +3 -0
  28. package/dist/src/autocomplete/__fixtures__/prog-autocomplete.d.ts.map +1 -0
  29. package/dist/src/autocomplete/__fixtures__/prog-autocomplete.js +24 -0
  30. package/dist/src/autocomplete/__fixtures__/prog-autocomplete.js.map +1 -0
  31. package/dist/src/autocomplete/__tests__/autocomplete.spec.d.ts +2 -0
  32. package/dist/src/autocomplete/__tests__/autocomplete.spec.d.ts.map +1 -0
  33. package/dist/src/autocomplete/__tests__/autocomplete.spec.js +119 -0
  34. package/dist/src/autocomplete/__tests__/autocomplete.spec.js.map +1 -0
  35. package/dist/src/autocomplete/index.d.ts +20 -0
  36. package/dist/src/autocomplete/index.d.ts.map +1 -0
  37. package/dist/src/autocomplete/index.js +172 -0
  38. package/dist/src/autocomplete/index.js.map +1 -0
  39. package/dist/src/autocomplete/types.d.ts +26 -0
  40. package/dist/src/autocomplete/types.d.ts.map +1 -0
  41. package/dist/src/autocomplete/types.js +3 -0
  42. package/dist/src/autocomplete/types.js.map +1 -0
  43. package/dist/src/command/__fixtures__/example-cmd.d.ts +8 -0
  44. package/dist/src/command/__fixtures__/example-cmd.d.ts.map +1 -0
  45. package/dist/src/command/__fixtures__/example-cmd.js +10 -0
  46. package/dist/src/command/__fixtures__/example-cmd.js.map +1 -0
  47. package/dist/src/command/__tests__/command.spec.d.ts +2 -0
  48. package/dist/src/command/__tests__/command.spec.d.ts.map +1 -0
  49. package/dist/src/command/__tests__/command.spec.js +510 -0
  50. package/dist/src/command/__tests__/command.spec.js.map +1 -0
  51. package/dist/src/command/__tests__/find.spec.d.ts +2 -0
  52. package/dist/src/command/__tests__/find.spec.d.ts.map +1 -0
  53. package/dist/src/command/__tests__/find.spec.js +31 -0
  54. package/dist/src/command/__tests__/find.spec.js.map +1 -0
  55. package/dist/src/command/__tests__/import.spec.d.ts +2 -0
  56. package/dist/src/command/__tests__/import.spec.d.ts.map +1 -0
  57. package/dist/src/command/__tests__/import.spec.js +17 -0
  58. package/dist/src/command/__tests__/import.spec.js.map +1 -0
  59. package/dist/src/command/__tests__/scan.spec.d.ts +2 -0
  60. package/dist/src/command/__tests__/scan.spec.d.ts.map +1 -0
  61. package/dist/src/command/__tests__/scan.spec.js +20 -0
  62. package/dist/src/command/__tests__/scan.spec.js.map +1 -0
  63. package/dist/src/command/find.d.ts +8 -0
  64. package/dist/src/command/find.d.ts.map +1 -0
  65. package/dist/src/command/find.js +47 -0
  66. package/dist/src/command/find.js.map +1 -0
  67. package/dist/src/command/import.d.ts +7 -0
  68. package/dist/src/command/import.d.ts.map +1 -0
  69. package/dist/src/command/import.js +47 -0
  70. package/dist/src/command/import.js.map +1 -0
  71. package/dist/src/command/index.d.ts +211 -0
  72. package/dist/src/command/index.d.ts.map +1 -0
  73. package/dist/src/command/index.js +374 -0
  74. package/dist/src/command/index.js.map +1 -0
  75. package/dist/src/command/scan.d.ts +4 -0
  76. package/dist/src/command/scan.d.ts.map +1 -0
  77. package/dist/src/command/scan.js +31 -0
  78. package/dist/src/command/scan.js.map +1 -0
  79. package/dist/src/command/validate-call.d.ts +8 -0
  80. package/dist/src/command/validate-call.d.ts.map +1 -0
  81. package/dist/src/command/validate-call.js +13 -0
  82. package/dist/src/command/validate-call.js.map +1 -0
  83. package/dist/src/config/index.d.ts +7 -0
  84. package/dist/src/config/index.d.ts.map +1 -0
  85. package/dist/src/config/index.js +24 -0
  86. package/dist/src/config/index.js.map +1 -0
  87. package/dist/src/error/__tests__/fatal.spec.d.ts +2 -0
  88. package/dist/src/error/__tests__/fatal.spec.d.ts.map +1 -0
  89. package/dist/src/error/__tests__/fatal.spec.js +34 -0
  90. package/dist/src/error/__tests__/fatal.spec.js.map +1 -0
  91. package/dist/src/error/action.d.ts +9 -0
  92. package/dist/src/error/action.d.ts.map +1 -0
  93. package/dist/src/error/action.js +16 -0
  94. package/dist/src/error/action.js.map +1 -0
  95. package/dist/src/error/base.d.ts +11 -0
  96. package/dist/src/error/base.d.ts.map +1 -0
  97. package/dist/src/error/base.js +18 -0
  98. package/dist/src/error/base.js.map +1 -0
  99. package/dist/src/error/fatal.d.ts +10 -0
  100. package/dist/src/error/fatal.d.ts.map +1 -0
  101. package/dist/src/error/fatal.js +27 -0
  102. package/dist/src/error/fatal.js.map +1 -0
  103. package/dist/src/error/index.d.ts +18 -0
  104. package/dist/src/error/index.d.ts.map +1 -0
  105. package/dist/src/error/index.js +34 -0
  106. package/dist/src/error/index.js.map +1 -0
  107. package/dist/src/error/invalid-validator.d.ts +10 -0
  108. package/dist/src/error/invalid-validator.d.ts.map +1 -0
  109. package/dist/src/error/invalid-validator.js +15 -0
  110. package/dist/src/error/invalid-validator.js.map +1 -0
  111. package/dist/src/error/missing-argument.d.ts +11 -0
  112. package/dist/src/error/missing-argument.d.ts.map +1 -0
  113. package/dist/src/error/missing-argument.js +20 -0
  114. package/dist/src/error/missing-argument.js.map +1 -0
  115. package/dist/src/error/missing-flag.d.ts +11 -0
  116. package/dist/src/error/missing-flag.d.ts.map +1 -0
  117. package/dist/src/error/missing-flag.js +20 -0
  118. package/dist/src/error/missing-flag.js.map +1 -0
  119. package/dist/src/error/multi-validation.d.ts +10 -0
  120. package/dist/src/error/multi-validation.d.ts.map +1 -0
  121. package/dist/src/error/multi-validation.js +26 -0
  122. package/dist/src/error/multi-validation.js.map +1 -0
  123. package/dist/src/error/no-action.d.ts +10 -0
  124. package/dist/src/error/no-action.d.ts.map +1 -0
  125. package/dist/src/error/no-action.js +22 -0
  126. package/dist/src/error/no-action.js.map +1 -0
  127. package/dist/src/error/option-synopsis-syntax.d.ts +9 -0
  128. package/dist/src/error/option-synopsis-syntax.d.ts.map +1 -0
  129. package/dist/src/error/option-synopsis-syntax.js +15 -0
  130. package/dist/src/error/option-synopsis-syntax.js.map +1 -0
  131. package/dist/src/error/too-many-arguments.d.ts +11 -0
  132. package/dist/src/error/too-many-arguments.d.ts.map +1 -0
  133. package/dist/src/error/too-many-arguments.js +25 -0
  134. package/dist/src/error/too-many-arguments.js.map +1 -0
  135. package/dist/src/error/unknown-command.d.ts +13 -0
  136. package/dist/src/error/unknown-command.d.ts.map +1 -0
  137. package/dist/src/error/unknown-command.js +44 -0
  138. package/dist/src/error/unknown-command.js.map +1 -0
  139. package/dist/src/error/unknown-option.d.ts +13 -0
  140. package/dist/src/error/unknown-option.d.ts.map +1 -0
  141. package/dist/src/error/unknown-option.js +40 -0
  142. package/dist/src/error/unknown-option.js.map +1 -0
  143. package/dist/src/error/validation.d.ts +17 -0
  144. package/dist/src/error/validation.d.ts.map +1 -0
  145. package/dist/src/error/validation.js +49 -0
  146. package/dist/src/error/validation.js.map +1 -0
  147. package/dist/src/help/__tests__/help.spec.d.ts +2 -0
  148. package/dist/src/help/__tests__/help.spec.d.ts.map +1 -0
  149. package/dist/src/help/__tests__/help.spec.js +130 -0
  150. package/dist/src/help/__tests__/help.spec.js.map +1 -0
  151. package/dist/src/help/__tests__/utils.spec.d.ts +2 -0
  152. package/dist/src/help/__tests__/utils.spec.d.ts.map +1 -0
  153. package/dist/src/help/__tests__/utils.spec.js +16 -0
  154. package/dist/src/help/__tests__/utils.spec.js.map +1 -0
  155. package/dist/src/help/index.d.ts +47 -0
  156. package/dist/src/help/index.d.ts.map +1 -0
  157. package/dist/src/help/index.js +131 -0
  158. package/dist/src/help/index.js.map +1 -0
  159. package/dist/src/help/templates/command.d.ts +7 -0
  160. package/dist/src/help/templates/command.d.ts.map +1 -0
  161. package/dist/src/help/templates/command.js +23 -0
  162. package/dist/src/help/templates/command.js.map +1 -0
  163. package/dist/src/help/templates/custom.d.ts +7 -0
  164. package/dist/src/help/templates/custom.d.ts.map +1 -0
  165. package/dist/src/help/templates/custom.js +24 -0
  166. package/dist/src/help/templates/custom.js.map +1 -0
  167. package/dist/src/help/templates/header.d.ts +7 -0
  168. package/dist/src/help/templates/header.d.ts.map +1 -0
  169. package/dist/src/help/templates/header.js +16 -0
  170. package/dist/src/help/templates/header.js.map +1 -0
  171. package/dist/src/help/templates/index.d.ts +10 -0
  172. package/dist/src/help/templates/index.d.ts.map +1 -0
  173. package/dist/src/help/templates/index.js +26 -0
  174. package/dist/src/help/templates/index.js.map +1 -0
  175. package/dist/src/help/templates/program.d.ts +7 -0
  176. package/dist/src/help/templates/program.d.ts.map +1 -0
  177. package/dist/src/help/templates/program.js +18 -0
  178. package/dist/src/help/templates/program.js.map +1 -0
  179. package/dist/src/help/templates/usage.d.ts +7 -0
  180. package/dist/src/help/templates/usage.d.ts.map +1 -0
  181. package/dist/src/help/templates/usage.js +19 -0
  182. package/dist/src/help/templates/usage.js.map +1 -0
  183. package/dist/src/help/types.d.ts +53 -0
  184. package/dist/src/help/types.d.ts.map +1 -0
  185. package/dist/src/help/types.js +3 -0
  186. package/dist/src/help/types.js.map +1 -0
  187. package/dist/src/help/utils.d.ts +9 -0
  188. package/dist/src/help/utils.d.ts.map +1 -0
  189. package/dist/src/help/utils.js +92 -0
  190. package/dist/src/help/utils.js.map +1 -0
  191. package/dist/src/index.d.ts +90 -0
  192. package/dist/src/index.d.ts.map +1 -0
  193. package/dist/src/index.js +111 -0
  194. package/dist/src/index.js.map +1 -0
  195. package/dist/src/logger/__tests__/logger.spec.d.ts +2 -0
  196. package/dist/src/logger/__tests__/logger.spec.d.ts.map +1 -0
  197. package/dist/src/logger/__tests__/logger.spec.js +56 -0
  198. package/dist/src/logger/__tests__/logger.spec.js.map +1 -0
  199. package/dist/src/logger/index.d.ts +6 -0
  200. package/dist/src/logger/index.d.ts.map +1 -0
  201. package/dist/src/logger/index.js +128 -0
  202. package/dist/src/logger/index.js.map +1 -0
  203. package/dist/src/option/__tests__/global.spec.d.ts +2 -0
  204. package/dist/src/option/__tests__/global.spec.d.ts.map +1 -0
  205. package/dist/src/option/__tests__/global.spec.js +121 -0
  206. package/dist/src/option/__tests__/global.spec.js.map +1 -0
  207. package/dist/src/option/__tests__/option.spec.d.ts +2 -0
  208. package/dist/src/option/__tests__/option.spec.d.ts.map +1 -0
  209. package/dist/src/option/__tests__/option.spec.js +111 -0
  210. package/dist/src/option/__tests__/option.spec.js.map +1 -0
  211. package/dist/src/option/find.d.ts +14 -0
  212. package/dist/src/option/find.d.ts.map +1 -0
  213. package/dist/src/option/find.js +17 -0
  214. package/dist/src/option/find.js.map +1 -0
  215. package/dist/src/option/index.d.ts +65 -0
  216. package/dist/src/option/index.d.ts.map +1 -0
  217. package/dist/src/option/index.js +230 -0
  218. package/dist/src/option/index.js.map +1 -0
  219. package/dist/src/option/mapping.d.ts +7 -0
  220. package/dist/src/option/mapping.d.ts.map +1 -0
  221. package/dist/src/option/mapping.js +21 -0
  222. package/dist/src/option/mapping.js.map +1 -0
  223. package/dist/src/option/utils.d.ts +35 -0
  224. package/dist/src/option/utils.d.ts.map +1 -0
  225. package/dist/src/option/utils.js +139 -0
  226. package/dist/src/option/utils.js.map +1 -0
  227. package/dist/src/option/validate.d.ts +15 -0
  228. package/dist/src/option/validate.d.ts.map +1 -0
  229. package/dist/src/option/validate.js +63 -0
  230. package/dist/src/option/validate.js.map +1 -0
  231. package/dist/src/parser/__tests__/parser.spec.d.ts +2 -0
  232. package/dist/src/parser/__tests__/parser.spec.d.ts.map +1 -0
  233. package/dist/src/parser/__tests__/parser.spec.js +343 -0
  234. package/dist/src/parser/__tests__/parser.spec.js.map +1 -0
  235. package/dist/src/parser/index.d.ts +17 -0
  236. package/dist/src/parser/index.d.ts.map +1 -0
  237. package/dist/src/parser/index.js +299 -0
  238. package/dist/src/parser/index.js.map +1 -0
  239. package/dist/src/program/__tests__/program.spec.d.ts +2 -0
  240. package/dist/src/program/__tests__/program.spec.d.ts.map +1 -0
  241. package/dist/src/program/__tests__/program.spec.js +261 -0
  242. package/dist/src/program/__tests__/program.spec.js.map +1 -0
  243. package/dist/src/program/index.d.ts +349 -0
  244. package/dist/src/program/index.d.ts.map +1 -0
  245. package/dist/src/program/index.js +584 -0
  246. package/dist/src/program/index.js.map +1 -0
  247. package/dist/src/types.d.ts +396 -0
  248. package/dist/src/types.d.ts.map +1 -0
  249. package/dist/src/types.js +51 -0
  250. package/dist/src/types.js.map +1 -0
  251. package/dist/src/utils/__tests__/fs.spec.d.ts +2 -0
  252. package/dist/src/utils/__tests__/fs.spec.d.ts.map +1 -0
  253. package/dist/src/utils/__tests__/fs.spec.js +14 -0
  254. package/dist/src/utils/__tests__/fs.spec.js.map +1 -0
  255. package/dist/src/utils/__tests__/levenshtein.spec.d.ts +2 -0
  256. package/dist/src/utils/__tests__/levenshtein.spec.d.ts.map +1 -0
  257. package/dist/src/utils/__tests__/levenshtein.spec.js +18 -0
  258. package/dist/src/utils/__tests__/levenshtein.spec.js.map +1 -0
  259. package/dist/src/utils/__tests__/suggest.spec.d.ts +2 -0
  260. package/dist/src/utils/__tests__/suggest.spec.d.ts.map +1 -0
  261. package/dist/src/utils/__tests__/suggest.spec.js +31 -0
  262. package/dist/src/utils/__tests__/suggest.spec.js.map +1 -0
  263. package/dist/src/utils/colorize.d.ts +2 -0
  264. package/dist/src/utils/colorize.d.ts.map +1 -0
  265. package/dist/src/utils/colorize.js +27 -0
  266. package/dist/src/utils/colorize.js.map +1 -0
  267. package/dist/src/utils/fs.d.ts +2 -0
  268. package/dist/src/utils/fs.d.ts.map +1 -0
  269. package/dist/src/utils/fs.js +19 -0
  270. package/dist/src/utils/fs.js.map +1 -0
  271. package/dist/src/utils/levenshtein.d.ts +6 -0
  272. package/dist/src/utils/levenshtein.d.ts.map +1 -0
  273. package/dist/src/utils/levenshtein.js +32 -0
  274. package/dist/src/utils/levenshtein.js.map +1 -0
  275. package/dist/src/utils/suggest.d.ts +15 -0
  276. package/dist/src/utils/suggest.d.ts.map +1 -0
  277. package/dist/src/utils/suggest.js +49 -0
  278. package/dist/src/utils/suggest.js.map +1 -0
  279. package/dist/src/utils/version.d.ts +2 -0
  280. package/dist/src/utils/version.d.ts.map +1 -0
  281. package/dist/src/utils/version.js +21 -0
  282. package/dist/src/utils/version.js.map +1 -0
  283. package/dist/src/utils/web/autocomplete.d.ts +12 -0
  284. package/dist/src/utils/web/autocomplete.d.ts.map +1 -0
  285. package/dist/src/utils/web/autocomplete.js +12 -0
  286. package/dist/src/utils/web/autocomplete.js.map +1 -0
  287. package/dist/src/utils/web/process.d.ts +15 -0
  288. package/dist/src/utils/web/process.d.ts.map +1 -0
  289. package/dist/src/utils/web/process.js +29 -0
  290. package/dist/src/utils/web/process.js.map +1 -0
  291. package/dist/src/validator/__tests__/array.spec.d.ts +2 -0
  292. package/dist/src/validator/__tests__/array.spec.d.ts.map +1 -0
  293. package/dist/src/validator/__tests__/array.spec.js +34 -0
  294. package/dist/src/validator/__tests__/array.spec.js.map +1 -0
  295. package/dist/src/validator/__tests__/caporal.spec.d.ts +2 -0
  296. package/dist/src/validator/__tests__/caporal.spec.d.ts.map +1 -0
  297. package/dist/src/validator/__tests__/caporal.spec.js +86 -0
  298. package/dist/src/validator/__tests__/caporal.spec.js.map +1 -0
  299. package/dist/src/validator/__tests__/function.spec.d.ts +2 -0
  300. package/dist/src/validator/__tests__/function.spec.d.ts.map +1 -0
  301. package/dist/src/validator/__tests__/function.spec.js +42 -0
  302. package/dist/src/validator/__tests__/function.spec.js.map +1 -0
  303. package/dist/src/validator/__tests__/regexp.spec.d.ts +2 -0
  304. package/dist/src/validator/__tests__/regexp.spec.d.ts.map +1 -0
  305. package/dist/src/validator/__tests__/regexp.spec.js +34 -0
  306. package/dist/src/validator/__tests__/regexp.spec.js.map +1 -0
  307. package/dist/src/validator/__tests__/utils.spec.d.ts +2 -0
  308. package/dist/src/validator/__tests__/utils.spec.d.ts.map +1 -0
  309. package/dist/src/validator/__tests__/utils.spec.js +66 -0
  310. package/dist/src/validator/__tests__/utils.spec.js.map +1 -0
  311. package/dist/src/validator/__tests__/validate.spec.d.ts +2 -0
  312. package/dist/src/validator/__tests__/validate.spec.d.ts.map +1 -0
  313. package/dist/src/validator/__tests__/validate.spec.js +25 -0
  314. package/dist/src/validator/__tests__/validate.spec.js.map +1 -0
  315. package/dist/src/validator/array.d.ts +14 -0
  316. package/dist/src/validator/array.d.ts.map +1 -0
  317. package/dist/src/validator/array.js +29 -0
  318. package/dist/src/validator/array.js.map +1 -0
  319. package/dist/src/validator/caporal.d.ts +25 -0
  320. package/dist/src/validator/caporal.d.ts.map +1 -0
  321. package/dist/src/validator/caporal.js +89 -0
  322. package/dist/src/validator/caporal.js.map +1 -0
  323. package/dist/src/validator/function.d.ts +7 -0
  324. package/dist/src/validator/function.d.ts.map +1 -0
  325. package/dist/src/validator/function.js +27 -0
  326. package/dist/src/validator/function.js.map +1 -0
  327. package/dist/src/validator/regexp.d.ts +14 -0
  328. package/dist/src/validator/regexp.d.ts.map +1 -0
  329. package/dist/src/validator/regexp.js +31 -0
  330. package/dist/src/validator/regexp.js.map +1 -0
  331. package/dist/src/validator/utils.d.ts +14 -0
  332. package/dist/src/validator/utils.d.ts.map +1 -0
  333. package/dist/src/validator/utils.js +81 -0
  334. package/dist/src/validator/utils.js.map +1 -0
  335. package/dist/src/validator/validate.d.ts +7 -0
  336. package/dist/src/validator/validate.d.ts.map +1 -0
  337. package/dist/src/validator/validate.js +29 -0
  338. package/dist/src/validator/validate.js.map +1 -0
  339. package/dist/tsconfig.tsbuildinfo +1 -0
  340. package/package.json +75 -0
  341. package/src/__tests__/issue-163.spec.ts +18 -0
  342. package/src/argument/__tests__/argument.spec.ts +84 -0
  343. package/src/argument/find.ts +11 -0
  344. package/src/argument/index.ts +35 -0
  345. package/src/argument/synopsis.ts +41 -0
  346. package/src/argument/validate.ts +176 -0
  347. package/src/autocomplete/__fixtures__/prog-autocomplete.ts +24 -0
  348. package/src/autocomplete/__tests__/autocomplete.spec.ts +129 -0
  349. package/src/autocomplete/index.ts +225 -0
  350. package/src/autocomplete/types.ts +29 -0
  351. package/src/command/__fixtures__/example-cmd.ts +14 -0
  352. package/src/command/__tests__/command.spec.ts +621 -0
  353. package/src/command/__tests__/find.spec.ts +32 -0
  354. package/src/command/__tests__/import.spec.ts +14 -0
  355. package/src/command/__tests__/scan.spec.ts +16 -0
  356. package/src/command/find.ts +57 -0
  357. package/src/command/import.ts +13 -0
  358. package/src/command/index.ts +458 -0
  359. package/src/command/scan.ts +30 -0
  360. package/src/command/validate-call.ts +19 -0
  361. package/src/config/index.ts +26 -0
  362. package/src/error/__tests__/fatal.spec.ts +38 -0
  363. package/src/error/action.ts +13 -0
  364. package/src/error/base.ts +20 -0
  365. package/src/error/fatal.ts +25 -0
  366. package/src/error/index.ts +17 -0
  367. package/src/error/invalid-validator.ts +12 -0
  368. package/src/error/missing-argument.ts +16 -0
  369. package/src/error/missing-flag.ts +16 -0
  370. package/src/error/multi-validation.ts +22 -0
  371. package/src/error/no-action.ts +19 -0
  372. package/src/error/option-synopsis-syntax.ts +12 -0
  373. package/src/error/too-many-arguments.ts +28 -0
  374. package/src/error/unknown-command.ts +41 -0
  375. package/src/error/unknown-option.ts +40 -0
  376. package/src/error/validation.ts +80 -0
  377. package/src/help/__tests__/__snapshots__/help.spec.ts.snap +334 -0
  378. package/src/help/__tests__/help.spec.ts +144 -0
  379. package/src/help/__tests__/utils.spec.ts +14 -0
  380. package/src/help/index.ts +107 -0
  381. package/src/help/templates/command.ts +27 -0
  382. package/src/help/templates/custom.ts +25 -0
  383. package/src/help/templates/header.ts +19 -0
  384. package/src/help/templates/index.ts +9 -0
  385. package/src/help/templates/program.ts +21 -0
  386. package/src/help/templates/usage.ts +24 -0
  387. package/src/help/types.ts +57 -0
  388. package/src/help/utils.ts +109 -0
  389. package/src/index.ts +93 -0
  390. package/src/logger/__tests__/logger.spec.ts +65 -0
  391. package/src/logger/index.ts +97 -0
  392. package/src/option/__tests__/global.spec.ts +141 -0
  393. package/src/option/__tests__/option.spec.ts +115 -0
  394. package/src/option/find.ts +17 -0
  395. package/src/option/index.ts +280 -0
  396. package/src/option/mapping.ts +17 -0
  397. package/src/option/utils.ts +141 -0
  398. package/src/option/validate.ts +80 -0
  399. package/src/parser/__tests__/parser.spec.ts +371 -0
  400. package/src/parser/index.ts +383 -0
  401. package/src/program/__tests__/program.spec.ts +316 -0
  402. package/src/program/index.ts +676 -0
  403. package/src/types.ts +432 -0
  404. package/src/utils/__tests__/fs.spec.ts +14 -0
  405. package/src/utils/__tests__/levenshtein.spec.ts +16 -0
  406. package/src/utils/__tests__/suggest.spec.ts +30 -0
  407. package/src/utils/colorize.ts +21 -0
  408. package/src/utils/fs.ts +13 -0
  409. package/src/utils/levenshtein.ts +28 -0
  410. package/src/utils/suggest.ts +52 -0
  411. package/src/utils/version.ts +14 -0
  412. package/src/utils/web/autocomplete.ts +19 -0
  413. package/src/utils/web/process.ts +24 -0
  414. package/src/validator/__tests__/array.spec.ts +41 -0
  415. package/src/validator/__tests__/caporal.spec.ts +132 -0
  416. package/src/validator/__tests__/function.spec.ts +52 -0
  417. package/src/validator/__tests__/regexp.spec.ts +38 -0
  418. package/src/validator/__tests__/utils.spec.ts +67 -0
  419. package/src/validator/__tests__/validate.spec.ts +24 -0
  420. package/src/validator/array.ts +31 -0
  421. package/src/validator/caporal.ts +104 -0
  422. package/src/validator/function.ts +31 -0
  423. package/src/validator/regexp.ts +34 -0
  424. package/src/validator/utils.ts +84 -0
  425. package/src/validator/validate.ts +38 -0
@@ -0,0 +1,621 @@
1
+ import { expect, it, describe, beforeEach, vi } from "vitest"
2
+
3
+ const mocks = vi.hoisted(() => {
4
+ return {
5
+ fatalError: vi.fn(),
6
+ }
7
+ })
8
+
9
+ vi.mock("../../error/fatal", () => ({
10
+ fatalError: mocks.fatalError,
11
+ }))
12
+
13
+ vi.useFakeTimers()
14
+
15
+ import { createCommand, HELP_CMD } from ".."
16
+ import { program } from "../../index"
17
+ import { Program } from "../../program"
18
+ import { NoActionError, ActionError, ValidationSummaryError } from "../../error"
19
+
20
+ let prog = program
21
+
22
+ describe("Command", () => {
23
+ beforeEach(() => {
24
+ prog = new Program()
25
+ prog.name("test-prog")
26
+ prog.bin("test-prog")
27
+ mocks.fatalError.mockClear()
28
+ })
29
+ it("createCommand() should create a basic command", () => {
30
+ const cmd = createCommand(prog, "order", "Order something")
31
+ expect(cmd).toMatchObject({
32
+ name: "order",
33
+ args: [],
34
+ options: [],
35
+ description: "Order something",
36
+ visible: true,
37
+ })
38
+ })
39
+
40
+ it(".alias() should alias the command", () => {
41
+ const cmd = createCommand(prog, "order", "Order something").alias("give-it-to-me")
42
+ expect(cmd.hasAlias("give-it-to-me")).toBe(true)
43
+ })
44
+
45
+ it(".argument() should add an argument to the command", () => {
46
+ const cmd = createCommand(prog, "order", "Order something").argument(
47
+ "<pizza-type>",
48
+ "Pizza type",
49
+ )
50
+ expect(cmd.args).toHaveLength(1)
51
+ })
52
+
53
+ it(".action() should set the command action", async () => {
54
+ const action = vi.fn()
55
+ const cmd = createCommand(prog, "order", "Order something").action(action)
56
+ await cmd.run({
57
+ args: [],
58
+ options: {},
59
+ rawOptions: {},
60
+ line: "",
61
+ rawArgv: [],
62
+ ddash: [],
63
+ })
64
+ expect(action).toHaveBeenCalled()
65
+ })
66
+
67
+ it(".command() should add another command", () => {
68
+ prog.command("order", "Order something").command("other", "other command")
69
+ // 2 + help command
70
+ expect(prog.getCommands()).toHaveLength(3)
71
+ })
72
+
73
+ it(".hide() should hide the command", () => {
74
+ const cmd = prog.command("order", "Order something").hide()
75
+ expect(cmd.visible).toBe(false)
76
+ })
77
+
78
+ it(".name should be empty for teh program-command", () => {
79
+ const cmd = prog.argument("<my-arg>", "My argument")
80
+ expect(cmd.name).toEqual("")
81
+ })
82
+
83
+ it("get autoCast() should return true by default", () => {
84
+ const cmd = prog.command("order", "Order something")
85
+ expect(cmd.autoCast).toBe(true)
86
+ })
87
+
88
+ it("get autoCast() should return false if disabled", () => {
89
+ const cmd = prog.command("order", "Order something")
90
+ cmd.cast(false)
91
+ expect(cmd.autoCast).toBe(false)
92
+ })
93
+
94
+ it("get autoCast() should return false is disabled on the program level", () => {
95
+ const cmd = prog.cast(false).command("order", "Order something")
96
+ expect(cmd.autoCast).toBe(false)
97
+ })
98
+
99
+ it(".default() should set the command as the program default command", () => {
100
+ const action = vi.fn()
101
+ const cmd = createCommand(prog, "order", "Order something").action(action)
102
+ cmd.default()
103
+ expect(prog.defaultCommand).toEqual(cmd)
104
+ })
105
+
106
+ it(".option() should add an option to the command", () => {
107
+ const cmd = prog
108
+ .command("order", "Order something")
109
+ .option("-t, --type <pizza-type>", "Pizza type")
110
+
111
+ expect(cmd.options).toHaveLength(1)
112
+ })
113
+
114
+ it(".run() should throw an Error when no action is defined for the command", async () => {
115
+ const cmd = prog
116
+ .command("order", "Order something")
117
+ .option("-t, --type <pizza-type>", "Pizza type")
118
+ await expect(cmd.run({ args: [], options: {} })).rejects.toBeInstanceOf(NoActionError)
119
+ })
120
+
121
+ it(".run() should throw an ValidationSummaryError when invalid exact arg count is provided", async () => {
122
+ const action = vi.fn()
123
+ const cmd = prog
124
+ .command("order", "Order something")
125
+ .argument("<location>", "Location")
126
+ .option("-t, --type <pizza-type>", "Pizza type")
127
+ .action(action)
128
+
129
+ await expect(cmd.run({ args: [], options: {} })).rejects.toBeInstanceOf(
130
+ ValidationSummaryError,
131
+ )
132
+ })
133
+
134
+ it(".run() should throw an ValidationSummaryError when invalid arg count (range) is provided", async () => {
135
+ const action = vi.fn()
136
+ const cmd = prog
137
+ .command("order", "Order something")
138
+ .argument("<location>", "Location")
139
+ .argument("[details]", "Details")
140
+ .option("-t, --type <pizza-type>", "Pizza type")
141
+ .action(action)
142
+
143
+ await expect(cmd.run({ args: [], options: {} })).rejects.toBeInstanceOf(
144
+ ValidationSummaryError,
145
+ )
146
+ })
147
+
148
+ it(".run() should throw an ValidationSummaryError when invalid arg count is provided, even for variadic args", async () => {
149
+ const action = vi.fn()
150
+ const cmd = prog
151
+ .command("order", "Order something")
152
+ .argument("<menu...>", "Menu (one or more)")
153
+ .option("-t, --type <pizza-type>", "Pizza type")
154
+ .action(action)
155
+
156
+ await expect(cmd.run({ args: [], options: {} })).rejects.toBeInstanceOf(
157
+ ValidationSummaryError,
158
+ )
159
+ })
160
+
161
+ it(".run() should throw an ActionError when action throws an `Error`", async () => {
162
+ const action = vi.fn(() => {
163
+ throw new Error("User Error")
164
+ })
165
+ const cmd = prog.command("order", "Order something").action(action)
166
+ await expect(cmd.run({ args: ["order"] })).rejects.toBeInstanceOf(ActionError)
167
+ expect(action).toHaveBeenCalled()
168
+ })
169
+
170
+ it(".run() should throw an ActionError when action throws a message", async () => {
171
+ const action = vi.fn(() => {
172
+ throw "User Error"
173
+ })
174
+ const cmd = prog.command("order", "Order something").action(action)
175
+ await expect(cmd.run({ args: ["order"] })).rejects.toBeInstanceOf(ActionError)
176
+ expect(action).toHaveBeenCalled()
177
+ })
178
+
179
+ it(".run() should throw an ActionError when action rejects", async () => {
180
+ const action = vi.fn().mockRejectedValue(new Error("Rejected!"))
181
+ const cmd = prog.command("order", "Order something").action(action)
182
+ await expect(cmd.run({ args: ["order"] })).rejects.toBeInstanceOf(ActionError)
183
+ expect(action).toHaveBeenCalled()
184
+ })
185
+
186
+ it("processing a global flag returning false should stop further processing such as running the action, and run should return -1", async () => {
187
+ const action = vi.fn()
188
+ const cmd = prog
189
+ .command("order", "Order something")
190
+ .action(action)
191
+ .option("-t, --type <pizza-type>", "Pizza type")
192
+ await expect(cmd.run({ args: ["order"], options: { help: true } })).resolves.toBe(-1)
193
+ expect(action).not.toHaveBeenCalled()
194
+ })
195
+
196
+ it("isHelpCommand() should return true for the help command", async () => {
197
+ const cmd = prog.command(HELP_CMD, "Help command")
198
+ expect(cmd.isHelpCommand()).toBe(true)
199
+ })
200
+
201
+ it("isHelpCommand() should return false for non-help command", async () => {
202
+ const cmd = prog.command("some command", "some command")
203
+ expect(cmd.isHelpCommand()).toBe(false)
204
+ })
205
+
206
+ it("getAliases() should return registered aliases", async () => {
207
+ const cmd = prog.command("order", "Order something").alias("my-alias", "my-alias2")
208
+ expect(cmd.getAliases()).toEqual(["my-alias", "my-alias2"])
209
+ })
210
+
211
+ it("getAliases() should return an empty array when no alias is registered", async () => {
212
+ const cmd = prog.command("order", "Order something")
213
+ expect(cmd.getAliases()).toEqual([])
214
+ })
215
+
216
+ it("command should be callable via its alias", async () => {
217
+ const action = vi.fn().mockReturnValue("hey!")
218
+ const cmd = prog.command("order", "Order something").alias("my-alias").action(action)
219
+ await expect(cmd.run({ args: ["my-alias"] })).resolves.toBe("hey!")
220
+ expect(action).toHaveBeenCalled()
221
+ })
222
+
223
+ it("command should be callable even if it's the program-command", async () => {
224
+ const action = vi.fn().mockReturnValue("hey!")
225
+ prog.argument("<type>", "Pizza type").action(action)
226
+ await expect(prog.run(["margherita"])).resolves.toBe("hey!")
227
+ expect(action).toHaveBeenCalled()
228
+ })
229
+
230
+ it("command should be able to process arguments without validator", async () => {
231
+ const action = vi.fn().mockReturnValue("hey!")
232
+ const cmd = prog
233
+ .command("order", "Order something")
234
+ .argument("<type>", "Pizza type")
235
+ .action(action)
236
+ const args = ["order", "pepperoni"]
237
+ await expect(cmd.run({ args })).resolves.toBe("hey!")
238
+ expect(action).toHaveBeenCalledWith(
239
+ expect.objectContaining({
240
+ args: { type: "pepperoni" },
241
+ }),
242
+ )
243
+ })
244
+
245
+ it("command should be able to handle variadic arguments", async () => {
246
+ const action = vi.fn().mockReturnValue("OK!")
247
+ prog
248
+ .command("order", "Order something")
249
+ .argument("<types...>", "Pizza types")
250
+ .action(action)
251
+ const args = ["order", "pepperoni", "regina"]
252
+ await prog.run(args)
253
+ expect(action).toHaveBeenCalledWith(
254
+ expect.objectContaining({
255
+ args: { types: ["pepperoni", "regina"] },
256
+ }),
257
+ )
258
+ })
259
+
260
+ it("command should check arguments range (variable)", async () => {
261
+ const action = vi.fn().mockReturnValue("hey!")
262
+ const cmd = prog
263
+ .command("order", "Order something")
264
+ .argument("<type>", "Pizza type")
265
+ .argument("<deliver-to>", "Address")
266
+ .argument("[amount]", "Pizza type")
267
+ .action(action)
268
+ const args = ["order", "pepperoni"]
269
+ await expect(cmd.run({ args })).rejects.toBeInstanceOf(ValidationSummaryError)
270
+ expect(action).not.toHaveBeenCalled()
271
+ })
272
+
273
+ describe(".run() should handle the call validation", () => {
274
+ it("with an (optional) argument having a default value", async () => {
275
+ const action = vi.fn().mockReturnValue("got it!")
276
+ const cmd = prog
277
+ .command("order", "Order something")
278
+ .argument("<type>", " Pizza type", { default: ["margherita", "regina"] })
279
+ .argument("[amount]", " Amount of pizza", {
280
+ validator: program.NUMBER,
281
+ default: 1,
282
+ })
283
+ .action(action)
284
+
285
+ await expect(cmd.run({ args: ["order", "margherita"] })).resolves.toBe("got it!")
286
+ expect(action).toHaveBeenCalledWith(
287
+ expect.objectContaining({
288
+ args: { type: "margherita", amount: 1 },
289
+ }),
290
+ )
291
+ })
292
+ it("without an (optional) argument without default value", async () => {
293
+ const action = vi.fn().mockReturnValue("got it!")
294
+ const cmd = prog
295
+ .command("order", "Order something")
296
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
297
+ .argument("[amount]", " Amount of pizza", { validator: program.NUMBER })
298
+ .action(action)
299
+ await expect(cmd.run({ args: ["order", "margherita"] })).resolves.toBe("got it!")
300
+ })
301
+
302
+ it("with options without validation", async () => {
303
+ const action = vi.fn().mockReturnValue("got it!")
304
+ prog
305
+ .command("order", "Order something")
306
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
307
+ .option("-a, --amount <number>", "Amount of pizza")
308
+ .action(action)
309
+ await expect(prog.run(["order", "margherita", "--amount", "23"])).resolves.toBe(
310
+ "got it!",
311
+ )
312
+ })
313
+
314
+ it("with options with validator and default value ", async () => {
315
+ const action = vi.fn().mockReturnValue("got it!")
316
+ prog
317
+ .command("order", "Order something")
318
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
319
+ .option("-a, --amount <number>", "Amount of pizza", {
320
+ validator: program.NUMBER,
321
+ default: 1,
322
+ })
323
+ .action(action)
324
+ await expect(prog.run(["order", "margherita", "--amount", "23"])).resolves.toBe(
325
+ "got it!",
326
+ )
327
+ })
328
+
329
+ it("with required option not provided", async () => {
330
+ const action = vi.fn().mockReturnValue("got it!")
331
+ prog
332
+ .command("order", "Order something")
333
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
334
+ .option("-a, --amount <number>", "Amount of pizza", { required: true })
335
+ .action(action)
336
+ await expect(prog.run(["order", "margherita"])).rejects.toBeInstanceOf(
337
+ ValidationSummaryError,
338
+ )
339
+ expect(action).not.toHaveBeenCalled()
340
+ })
341
+
342
+ it("with options not provided but having default value ", async () => {
343
+ const action = vi.fn().mockReturnValue("got it!")
344
+ const cmd = prog
345
+ .command("order", "Order something")
346
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
347
+ .option("-a, --amount <number>", " Amount of pizza", {
348
+ validator: program.NUMBER,
349
+ default: 1,
350
+ })
351
+ .action(action)
352
+ await expect(cmd.run({ args: ["order", "margherita"] })).resolves.toBe("got it!")
353
+ })
354
+
355
+ it("with required options not provided and not having default value ", async () => {
356
+ const action = vi.fn().mockReturnValue("got it!")
357
+ const cmd = prog
358
+ .command("order", "Order something")
359
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
360
+ .option("-a, --amount <number>", "Amount of pizza", {
361
+ validator: program.NUMBER,
362
+ required: true,
363
+ })
364
+ .action(action)
365
+ await expect(cmd.run({ args: ["order", "margherita"] })).rejects.toBeInstanceOf(
366
+ ValidationSummaryError,
367
+ )
368
+ expect(action).not.toHaveBeenCalled()
369
+ })
370
+
371
+ it("should fail with missing arg ", async () => {
372
+ const action = vi.fn().mockReturnValue("got it!")
373
+ prog
374
+ .command("order", "Order something")
375
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
376
+ .action(action)
377
+
378
+ await expect(prog.run(["order"])).rejects.toBeInstanceOf(ValidationSummaryError)
379
+ expect(action).not.toHaveBeenCalled()
380
+ })
381
+
382
+ it("should fail when an argument is invalid", async () => {
383
+ const action = vi.fn().mockReturnValue("got it!")
384
+ prog
385
+ .command("cancel", "cancel an order id")
386
+ .argument("<order-id>", "Order ID", { validator: program.NUMBER })
387
+ .action(action)
388
+
389
+ await expect(prog.run(["cancel", "not-a-number"])).rejects.toBeInstanceOf(
390
+ ValidationSummaryError,
391
+ )
392
+ expect(action).not.toHaveBeenCalled()
393
+ })
394
+
395
+ it("should fail for the program-command when too many args are provided and config.strictArgsCount = true ", async () => {
396
+ const action = vi.fn().mockReturnValue("got it!")
397
+ prog
398
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
399
+ .action(action)
400
+ await expect(prog.run(["margherita", "unknown-arg"])).rejects.toBeInstanceOf(
401
+ ValidationSummaryError,
402
+ )
403
+ vi.runAllTimers()
404
+ expect(action).not.toHaveBeenCalled()
405
+ expect(mocks.fatalError).not.toHaveBeenCalled()
406
+ })
407
+
408
+ it("should fail when too many args are provided and config.strictArgsCount = true ", async () => {
409
+ const action = vi.fn().mockReturnValue("got it!")
410
+ prog
411
+ .command("order", "Order something")
412
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
413
+ .action(action)
414
+
415
+ await expect(
416
+ prog.run(["order", "margherita", "unknown-arg"]),
417
+ ).rejects.toBeInstanceOf(ValidationSummaryError)
418
+ vi.runAllTimers()
419
+ expect(action).not.toHaveBeenCalled()
420
+ expect(mocks.fatalError).not.toHaveBeenCalled()
421
+ })
422
+
423
+ it("should fail when too many args are provided (and a range is expected) and config.strictArgsCount = true ", async () => {
424
+ const action = vi.fn().mockReturnValue("got it!")
425
+ prog
426
+ .command("order", "Order something")
427
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
428
+ .argument("[addon]", "Addon")
429
+ .action(action)
430
+ await expect(
431
+ prog.run(["order", "margherita", "my-addon", "unknown-arg"]),
432
+ ).rejects.toBeInstanceOf(ValidationSummaryError)
433
+
434
+ vi.runAllTimers()
435
+ expect(action).not.toHaveBeenCalled()
436
+ })
437
+
438
+ it("should not fail when too many args are provided and config.strictArgsCount = false ", async () => {
439
+ const action = vi.fn().mockReturnValue("got it!")
440
+ prog
441
+ .configure({ strictArgsCount: false })
442
+ .command("order", "Order something")
443
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
444
+ .action(action)
445
+
446
+ await prog.run(["order", "margherita", "unknown-arg"])
447
+ expect(action).toHaveBeenCalled()
448
+ })
449
+
450
+ it("should fail with unknown option ", async () => {
451
+ const action = vi.fn().mockReturnValue("got it!")
452
+ prog
453
+ .command("order", "Order something")
454
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
455
+ .action(action)
456
+
457
+ await expect(
458
+ prog.run(["order", "margherita", "--unknown", "foo"]),
459
+ ).rejects.toBeInstanceOf(ValidationSummaryError)
460
+
461
+ expect(action).not.toHaveBeenCalled()
462
+ })
463
+
464
+ it("should not fail with unknown option when config.strictOptions = false", async () => {
465
+ const action = vi.fn().mockReturnValue("got it!")
466
+ prog
467
+ .configure({ strictOptions: false })
468
+ .command("order", "Order something")
469
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
470
+ .action(action)
471
+
472
+ await expect(prog.run(["order", "margherita", "--unknown", "foo"])).resolves.toBe(
473
+ "got it!",
474
+ )
475
+ expect(action).toHaveBeenCalled()
476
+ })
477
+
478
+ it("should fail with unknown option and suggest valid options", async () => {
479
+ const action = vi.fn().mockReturnValue("got it!")
480
+ prog
481
+ .command("order", "Order something")
482
+ .argument("<type>", "Pizza type", { validator: ["margherita", "regina"] })
483
+ .option("--file", "File")
484
+ .action(action)
485
+
486
+ await expect(
487
+ prog.run(["order", "margherita", "--fime", "foo"]),
488
+ ).rejects.toBeInstanceOf(ValidationSummaryError)
489
+
490
+ expect(action).not.toHaveBeenCalled()
491
+ })
492
+
493
+ it("with non required flag not provided and not having default value ", async () => {
494
+ const action = vi.fn().mockReturnValue("got it!")
495
+ prog
496
+ .command("order", "Order something")
497
+ .argument("<type>", " Pizza type", { validator: ["margherita", "regina"] })
498
+ .option("-a, --amount <number>", " Amount of pizza", {
499
+ validator: program.NUMBER,
500
+ })
501
+ .action(action)
502
+ await expect(prog.run(["order", "margherita"])).resolves.toBe("got it!")
503
+ })
504
+ })
505
+
506
+ it(".getParserConfig() should return the correct default parser config", () => {
507
+ const cmd = createCommand(prog, "order", "Order something")
508
+ const config = cmd.getParserConfig()
509
+ expect(config).toMatchObject({
510
+ alias: {},
511
+ autoCast: true,
512
+ boolean: [],
513
+ ddash: false,
514
+ string: [],
515
+ variadic: [],
516
+ })
517
+ })
518
+
519
+ it(".getParserConfig() should return the correct parser config for args & options", () => {
520
+ const cmd = createCommand(prog, "invite", "Invite people")
521
+ .argument("<guests>", "Number of guests", { validator: program.NUMBER })
522
+ .argument("<location>", "Number of guests", { validator: program.STRING })
523
+ .argument("<send-email>", "Send a confirmation email", {
524
+ validator: program.BOOLEAN,
525
+ })
526
+ .argument("<email-list>", "List of emails, comma-separated", {
527
+ validator: program.ARRAY | program.STRING,
528
+ })
529
+ .argument("<names...>", "Guests names", { validator: program.STRING })
530
+ .option("--send-sms", "Send SMS")
531
+ .option("--save-to", "Save to", { validator: program.STRING }) // TODO: wrong declaration!
532
+ .option("--rsvp <response>", "Ask for RSVP", {
533
+ validator: program.BOOLEAN,
534
+ })
535
+ .option("-m, --max <num>", "max invite", {
536
+ validator: program.NUMBER,
537
+ })
538
+ .option("--override <key:value...>", "override config")
539
+ const config = cmd.getParserConfig()
540
+ expect(config).toMatchObject({
541
+ alias: {},
542
+ autoCast: true,
543
+ boolean: expect.arrayContaining([3, "sendSms", "rsvp"]),
544
+ ddash: false,
545
+ string: expect.arrayContaining([2, "saveTo", 4, 5]),
546
+ variadic: expect.arrayContaining([5, "override"]),
547
+ })
548
+ })
549
+
550
+ it(".synopsis should return the correct synopsis when all flags are optional", () => {
551
+ const cmd = createCommand(prog, "invite", "Invite people")
552
+ .argument("<guests>", "Number of guests", { validator: program.NUMBER })
553
+ .argument("<location>", "Number of guests", { validator: program.STRING })
554
+ .argument("<send-email>", "Send a confirmation email", {
555
+ validator: program.BOOLEAN,
556
+ })
557
+ .argument("<email-list>", "List of emails, comma-separated", {
558
+ validator: program.ARRAY | program.STRING,
559
+ })
560
+ .argument("<names...>", "Guests names", { validator: program.STRING })
561
+ .option("--send-sms", "Send SMS")
562
+ .option("--save-to", "Save to", { validator: program.STRING }) // TODO: wrong declaration!
563
+ .option("--rsvp <response>", "Ask for RSVP", {
564
+ validator: program.BOOLEAN,
565
+ })
566
+ .option("-m, --max <num>", "max invite", {
567
+ validator: program.NUMBER,
568
+ })
569
+ .option("--override <key:value...>", "override config")
570
+ expect(cmd.synopsis).toBe(
571
+ "test-prog invite <guests> <location> <send-email> <email-list> <names...> [OPTIONS...]",
572
+ )
573
+ })
574
+
575
+ it(".synopsis should return the correct synopsis when some flags are required", () => {
576
+ const cmd = createCommand(prog, "invite", "Invite people")
577
+ .argument("<guests>", "Number of guests", { validator: program.NUMBER })
578
+ .argument("<location>", "Number of guests", { validator: program.STRING })
579
+ .argument("<send-email>", "Send a confirmation email", {
580
+ validator: program.BOOLEAN,
581
+ })
582
+ .argument("<email-list>", "List of emails, comma-separated", {
583
+ validator: program.ARRAY | program.STRING,
584
+ })
585
+ .argument("<names...>", "Guests names", { validator: program.STRING })
586
+ .option("--send-sms", "Send SMS")
587
+ .option("--save-to", "Save to", { validator: program.STRING }) // TODO: wrong declaration!
588
+ .option("--rsvp <response>", "Ask for RSVP", {
589
+ validator: program.BOOLEAN,
590
+ required: true,
591
+ })
592
+ .option("-m, --max <num>", "max invite", {
593
+ validator: program.NUMBER,
594
+ })
595
+ .option("--override <key:value...>", "override config")
596
+ expect(cmd.synopsis).toBe(
597
+ "test-prog invite <guests> <location> <send-email> <email-list> <names...> <OPTIONS...>",
598
+ )
599
+ })
600
+
601
+ it(".synopsis should return the correct synopsis when command does not have any flags", () => {
602
+ const cmd = createCommand(prog, "invite", "Invite people")
603
+ .argument("<guests>", "Number of guests", { validator: program.NUMBER })
604
+ .argument("<location>", "Number of guests", { validator: program.STRING })
605
+ .argument("<send-email>", "Send a confirmation email", {
606
+ validator: program.BOOLEAN,
607
+ })
608
+ .argument("<email-list>", "List of emails, comma-separated", {
609
+ validator: program.ARRAY | program.STRING,
610
+ })
611
+ .argument("<names...>", "Guests names", { validator: program.STRING })
612
+ expect(cmd.synopsis).toBe(
613
+ "test-prog invite <guests> <location> <send-email> <email-list> <names...>",
614
+ )
615
+ })
616
+
617
+ it(".synopsis should return the correct synopsis for a program-command", () => {
618
+ const cmd = prog.argument("<foo>", "my desc")
619
+ expect(cmd.synopsis).toBe("test-prog <foo>")
620
+ })
621
+ })
@@ -0,0 +1,32 @@
1
+ import { expect, it, describe, vi } from "vitest"
2
+ import { createCommand } from ".."
3
+ import { Program } from "../../program"
4
+ import { findCommand } from "../find"
5
+
6
+ const mocks = vi.hoisted(() => {
7
+ return {
8
+ importCommand: vi.fn(),
9
+ }
10
+ })
11
+
12
+ vi.mock("../import", () => ({
13
+ importCommand: mocks.importCommand,
14
+ }))
15
+
16
+ describe("Command", () => {
17
+ const prog = new Program()
18
+ prog.discover(".")
19
+ const knownCmd = prog.command("my-command", "my command")
20
+ const discoverableCmd = createCommand(prog, "discoverable", "my command")
21
+ const commandCreator = vi.fn(() => discoverableCmd)
22
+ mocks.importCommand.mockResolvedValue(commandCreator)
23
+
24
+ describe("findCommand()", () => {
25
+ it("should find a known command", () => {
26
+ return expect(findCommand(prog, ["my-command"])).resolves.toEqual(knownCmd)
27
+ })
28
+ it("should find a discoverable command", () => {
29
+ return expect(findCommand(prog, ["git init"])).resolves.toEqual(discoverableCmd)
30
+ })
31
+ })
32
+ })
@@ -0,0 +1,14 @@
1
+ import { importCommand } from "../import"
2
+ import path from "path"
3
+ import { expect, it, describe } from "vitest"
4
+
5
+ describe("Command", () => {
6
+ describe("importCommand()", () => {
7
+ it("should import a command from a file", async () => {
8
+ const creator = await importCommand(
9
+ path.resolve(__dirname, "../__fixtures__/example-cmd.ts"),
10
+ )
11
+ expect(creator).toBeTruthy()
12
+ })
13
+ })
14
+ })
@@ -0,0 +1,16 @@
1
+ import { scanCommands } from "../scan"
2
+ import { Program } from "../../program"
3
+ import path from "path"
4
+ import { Command } from ".."
5
+ import { expect, it, describe } from "vitest"
6
+
7
+ describe("scanCommands()", () => {
8
+ const prog = new Program()
9
+
10
+ it("should scan commands", async () => {
11
+ const commands = await scanCommands(prog, path.join(__dirname, "../__fixtures__/"))
12
+ commands.forEach((cmd) => {
13
+ expect(cmd).toBeInstanceOf(Command)
14
+ })
15
+ })
16
+ })