zod-args-parser 2.0.0-alpha.0 → 2.0.0-beta.1

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 (510) hide show
  1. package/README.md +525 -588
  2. package/lib/cjs/autocomplete-scripts/bash-autocomplete-script.cjs +2 -0
  3. package/lib/cjs/autocomplete-scripts/bash-autocomplete-script.cjs.map +1 -0
  4. package/lib/cjs/autocomplete-scripts/powershell-autocomplete-script.cjs +2 -0
  5. package/lib/cjs/autocomplete-scripts/powershell-autocomplete-script.cjs.map +1 -0
  6. package/lib/cjs/autocomplete-scripts/zsh-autocomplete-script.cjs +42 -0
  7. package/lib/cjs/autocomplete-scripts/zsh-autocomplete-script.cjs.map +1 -0
  8. package/lib/cjs/coerce/coerce-methods.cjs +2 -0
  9. package/lib/cjs/coerce/coerce-methods.cjs.map +1 -0
  10. package/lib/cjs/coerce/string-to-array.cjs +2 -0
  11. package/lib/cjs/coerce/string-to-array.cjs.map +1 -0
  12. package/lib/cjs/coerce/string-to-primitive.cjs +2 -0
  13. package/lib/cjs/coerce/string-to-primitive.cjs.map +1 -0
  14. package/lib/cjs/coerce/string-to-set.cjs +2 -0
  15. package/lib/cjs/coerce/string-to-set.cjs.map +1 -0
  16. package/lib/cjs/definitions/define-arguments.cjs +2 -0
  17. package/lib/cjs/definitions/define-arguments.cjs.map +1 -0
  18. package/lib/cjs/definitions/define-cli.cjs +2 -0
  19. package/lib/cjs/definitions/define-cli.cjs.map +1 -0
  20. package/lib/cjs/definitions/define-options.cjs +2 -0
  21. package/lib/cjs/definitions/define-options.cjs.map +1 -0
  22. package/lib/cjs/definitions/define-subcommand.cjs +2 -0
  23. package/lib/cjs/definitions/define-subcommand.cjs.map +1 -0
  24. package/lib/cjs/definitions/validate-cli-definition.cjs +2 -0
  25. package/lib/cjs/definitions/validate-cli-definition.cjs.map +1 -0
  26. package/lib/cjs/help-message/format-arguments.cjs +2 -0
  27. package/lib/cjs/help-message/format-arguments.cjs.map +1 -0
  28. package/lib/cjs/help-message/format-options.cjs +2 -0
  29. package/lib/cjs/help-message/format-options.cjs.map +1 -0
  30. package/lib/cjs/help-message/format-subcommands.cjs +2 -0
  31. package/lib/cjs/help-message/format-subcommands.cjs.map +1 -0
  32. package/lib/cjs/help-message/generate-for-cli.cjs +2 -0
  33. package/lib/cjs/help-message/generate-for-cli.cjs.map +1 -0
  34. package/lib/cjs/help-message/generate-for-subcommand.cjs +2 -0
  35. package/lib/cjs/help-message/generate-for-subcommand.cjs.map +1 -0
  36. package/lib/cjs/help-message/print-help.cjs +2 -0
  37. package/lib/cjs/help-message/print-help.cjs.map +1 -0
  38. package/lib/cjs/help-message/set-defaults.cjs +2 -0
  39. package/lib/cjs/help-message/set-defaults.cjs.map +1 -0
  40. package/lib/cjs/help-message/styles.cjs +2 -0
  41. package/lib/cjs/help-message/styles.cjs.map +1 -0
  42. package/lib/cjs/help-message/terminal-markdown.cjs +2 -0
  43. package/lib/cjs/help-message/terminal-markdown.cjs.map +1 -0
  44. package/lib/cjs/index.cjs +2 -0
  45. package/lib/cjs/index.cjs.map +1 -0
  46. package/lib/cjs/markdown/generate-markdown.cjs +2 -0
  47. package/lib/cjs/markdown/generate-markdown.cjs.map +1 -0
  48. package/lib/cjs/metadata/arguments-metadata.cjs +2 -0
  49. package/lib/cjs/metadata/arguments-metadata.cjs.map +1 -0
  50. package/lib/cjs/metadata/cli-metadata.cjs +2 -0
  51. package/lib/cjs/metadata/cli-metadata.cjs.map +1 -0
  52. package/lib/cjs/metadata/options-metadata.cjs +2 -0
  53. package/lib/cjs/metadata/options-metadata.cjs.map +1 -0
  54. package/lib/cjs/metadata/subcommands-metadata.cjs +2 -0
  55. package/lib/cjs/metadata/subcommands-metadata.cjs.map +1 -0
  56. package/lib/cjs/parse/context/cli-context-builder.cjs +2 -0
  57. package/lib/cjs/parse/context/cli-context-builder.cjs.map +1 -0
  58. package/lib/cjs/parse/context/object-context-builder.cjs +2 -0
  59. package/lib/cjs/parse/context/object-context-builder.cjs.map +1 -0
  60. package/lib/cjs/parse/parser-utilities.cjs +2 -0
  61. package/lib/cjs/parse/parser-utilities.cjs.map +1 -0
  62. package/lib/cjs/parse/safe-parse.cjs +2 -0
  63. package/lib/cjs/parse/safe-parse.cjs.map +1 -0
  64. package/lib/cjs/parse/validation/validate-context.cjs +2 -0
  65. package/lib/cjs/parse/validation/validate-context.cjs.map +1 -0
  66. package/lib/cjs/parse/validation/validators/arguments.cjs +2 -0
  67. package/lib/cjs/parse/validation/validators/arguments.cjs.map +1 -0
  68. package/lib/cjs/parse/validation/validators/conflict.cjs +2 -0
  69. package/lib/cjs/parse/validation/validators/conflict.cjs.map +1 -0
  70. package/lib/cjs/parse/validation/validators/exclusive.cjs +2 -0
  71. package/lib/cjs/parse/validation/validators/exclusive.cjs.map +1 -0
  72. package/lib/cjs/parse/validation/validators/explicitly-passed.cjs +2 -0
  73. package/lib/cjs/parse/validation/validators/explicitly-passed.cjs.map +1 -0
  74. package/lib/cjs/parse/validation/validators/options.cjs +2 -0
  75. package/lib/cjs/parse/validation/validators/options.cjs.map +1 -0
  76. package/lib/cjs/parse/validation/validators/requires.cjs +2 -0
  77. package/lib/cjs/parse/validation/validators/requires.cjs.map +1 -0
  78. package/lib/cjs/utilities.cjs +2 -0
  79. package/lib/cjs/utilities.cjs.map +1 -0
  80. package/lib/esm/autocomplete-scripts/bash-autocomplete-script.js +2 -0
  81. package/lib/esm/autocomplete-scripts/bash-autocomplete-script.js.map +1 -0
  82. package/lib/esm/autocomplete-scripts/powershell-autocomplete-script.js +2 -0
  83. package/lib/esm/autocomplete-scripts/powershell-autocomplete-script.js.map +1 -0
  84. package/lib/esm/autocomplete-scripts/zsh-autocomplete-script.js +42 -0
  85. package/lib/esm/autocomplete-scripts/zsh-autocomplete-script.js.map +1 -0
  86. package/lib/esm/coerce/coerce-methods.js +2 -0
  87. package/lib/esm/coerce/coerce-methods.js.map +1 -0
  88. package/lib/esm/coerce/string-to-array.js +2 -0
  89. package/lib/esm/coerce/string-to-array.js.map +1 -0
  90. package/lib/esm/coerce/string-to-primitive.js +2 -0
  91. package/lib/esm/coerce/string-to-primitive.js.map +1 -0
  92. package/lib/esm/coerce/string-to-set.js +2 -0
  93. package/lib/esm/coerce/string-to-set.js.map +1 -0
  94. package/lib/esm/definitions/define-arguments.js +2 -0
  95. package/lib/esm/definitions/define-arguments.js.map +1 -0
  96. package/lib/esm/definitions/define-cli.js +2 -0
  97. package/lib/esm/definitions/define-cli.js.map +1 -0
  98. package/lib/esm/definitions/define-options.js +2 -0
  99. package/lib/esm/definitions/define-options.js.map +1 -0
  100. package/lib/esm/definitions/define-subcommand.js +2 -0
  101. package/lib/esm/definitions/define-subcommand.js.map +1 -0
  102. package/lib/esm/definitions/validate-cli-definition.js +2 -0
  103. package/lib/esm/definitions/validate-cli-definition.js.map +1 -0
  104. package/lib/esm/help-message/format-arguments.js +2 -0
  105. package/lib/esm/help-message/format-arguments.js.map +1 -0
  106. package/lib/esm/help-message/format-options.js +2 -0
  107. package/lib/esm/help-message/format-options.js.map +1 -0
  108. package/lib/esm/help-message/format-subcommands.js +2 -0
  109. package/lib/esm/help-message/format-subcommands.js.map +1 -0
  110. package/lib/esm/help-message/generate-for-cli.js +2 -0
  111. package/lib/esm/help-message/generate-for-cli.js.map +1 -0
  112. package/lib/esm/help-message/generate-for-subcommand.js +2 -0
  113. package/lib/esm/help-message/generate-for-subcommand.js.map +1 -0
  114. package/lib/esm/help-message/print-help.js +2 -0
  115. package/lib/esm/help-message/print-help.js.map +1 -0
  116. package/lib/esm/help-message/set-defaults.js +2 -0
  117. package/lib/esm/help-message/set-defaults.js.map +1 -0
  118. package/lib/esm/help-message/styles.js +2 -0
  119. package/lib/esm/help-message/styles.js.map +1 -0
  120. package/lib/esm/help-message/terminal-markdown.js +2 -0
  121. package/lib/esm/help-message/terminal-markdown.js.map +1 -0
  122. package/lib/esm/index.js +2 -0
  123. package/lib/esm/index.js.map +1 -0
  124. package/lib/esm/markdown/generate-markdown.js +2 -0
  125. package/lib/esm/markdown/generate-markdown.js.map +1 -0
  126. package/lib/esm/metadata/arguments-metadata.js +2 -0
  127. package/lib/esm/metadata/arguments-metadata.js.map +1 -0
  128. package/lib/esm/metadata/cli-metadata.js +2 -0
  129. package/lib/esm/metadata/cli-metadata.js.map +1 -0
  130. package/lib/esm/metadata/options-metadata.js +2 -0
  131. package/lib/esm/metadata/options-metadata.js.map +1 -0
  132. package/lib/esm/metadata/subcommands-metadata.js +2 -0
  133. package/lib/esm/metadata/subcommands-metadata.js.map +1 -0
  134. package/lib/esm/parse/context/cli-context-builder.js +2 -0
  135. package/lib/esm/parse/context/cli-context-builder.js.map +1 -0
  136. package/lib/esm/parse/context/object-context-builder.js +2 -0
  137. package/lib/esm/parse/context/object-context-builder.js.map +1 -0
  138. package/lib/esm/parse/parser-utilities.js +2 -0
  139. package/lib/esm/parse/parser-utilities.js.map +1 -0
  140. package/lib/esm/parse/safe-parse.js +2 -0
  141. package/lib/esm/parse/safe-parse.js.map +1 -0
  142. package/lib/esm/parse/validation/validate-context.js +2 -0
  143. package/lib/esm/parse/validation/validate-context.js.map +1 -0
  144. package/lib/esm/parse/validation/validators/arguments.js +2 -0
  145. package/lib/esm/parse/validation/validators/arguments.js.map +1 -0
  146. package/lib/esm/parse/validation/validators/conflict.js +2 -0
  147. package/lib/esm/parse/validation/validators/conflict.js.map +1 -0
  148. package/lib/esm/parse/validation/validators/exclusive.js +2 -0
  149. package/lib/esm/parse/validation/validators/exclusive.js.map +1 -0
  150. package/lib/esm/parse/validation/validators/explicitly-passed.js +2 -0
  151. package/lib/esm/parse/validation/validators/explicitly-passed.js.map +1 -0
  152. package/lib/esm/parse/validation/validators/options.js +2 -0
  153. package/lib/esm/parse/validation/validators/options.js.map +1 -0
  154. package/lib/esm/parse/validation/validators/requires.js +2 -0
  155. package/lib/esm/parse/validation/validators/requires.js.map +1 -0
  156. package/lib/esm/utilities.js +2 -0
  157. package/lib/esm/utilities.js.map +1 -0
  158. package/lib/iife/index.js +2 -0
  159. package/lib/iife/index.js.map +1 -0
  160. package/lib/mjs/autocomplete-scripts/bash-autocomplete-script.mjs +2 -0
  161. package/lib/mjs/autocomplete-scripts/bash-autocomplete-script.mjs.map +1 -0
  162. package/lib/mjs/autocomplete-scripts/powershell-autocomplete-script.mjs +2 -0
  163. package/lib/mjs/autocomplete-scripts/powershell-autocomplete-script.mjs.map +1 -0
  164. package/lib/mjs/autocomplete-scripts/zsh-autocomplete-script.mjs +42 -0
  165. package/lib/mjs/autocomplete-scripts/zsh-autocomplete-script.mjs.map +1 -0
  166. package/lib/mjs/coerce/coerce-methods.mjs +2 -0
  167. package/lib/mjs/coerce/coerce-methods.mjs.map +1 -0
  168. package/lib/mjs/coerce/string-to-array.mjs +2 -0
  169. package/lib/mjs/coerce/string-to-array.mjs.map +1 -0
  170. package/lib/mjs/coerce/string-to-primitive.mjs +2 -0
  171. package/lib/mjs/coerce/string-to-primitive.mjs.map +1 -0
  172. package/lib/mjs/coerce/string-to-set.mjs +2 -0
  173. package/lib/mjs/coerce/string-to-set.mjs.map +1 -0
  174. package/lib/mjs/definitions/define-arguments.mjs +2 -0
  175. package/lib/mjs/definitions/define-arguments.mjs.map +1 -0
  176. package/lib/mjs/definitions/define-cli.mjs +2 -0
  177. package/lib/mjs/definitions/define-cli.mjs.map +1 -0
  178. package/lib/mjs/definitions/define-options.mjs +2 -0
  179. package/lib/mjs/definitions/define-options.mjs.map +1 -0
  180. package/lib/mjs/definitions/define-subcommand.mjs +2 -0
  181. package/lib/mjs/definitions/define-subcommand.mjs.map +1 -0
  182. package/lib/mjs/definitions/validate-cli-definition.mjs +2 -0
  183. package/lib/mjs/definitions/validate-cli-definition.mjs.map +1 -0
  184. package/lib/mjs/help-message/format-arguments.mjs +2 -0
  185. package/lib/mjs/help-message/format-arguments.mjs.map +1 -0
  186. package/lib/mjs/help-message/format-options.mjs +2 -0
  187. package/lib/mjs/help-message/format-options.mjs.map +1 -0
  188. package/lib/mjs/help-message/format-subcommands.mjs +2 -0
  189. package/lib/mjs/help-message/format-subcommands.mjs.map +1 -0
  190. package/lib/mjs/help-message/generate-for-cli.mjs +2 -0
  191. package/lib/mjs/help-message/generate-for-cli.mjs.map +1 -0
  192. package/lib/mjs/help-message/generate-for-subcommand.mjs +2 -0
  193. package/lib/mjs/help-message/generate-for-subcommand.mjs.map +1 -0
  194. package/lib/mjs/help-message/print-help.mjs +2 -0
  195. package/lib/mjs/help-message/print-help.mjs.map +1 -0
  196. package/lib/mjs/help-message/set-defaults.mjs +2 -0
  197. package/lib/mjs/help-message/set-defaults.mjs.map +1 -0
  198. package/lib/mjs/help-message/styles.mjs +2 -0
  199. package/lib/mjs/help-message/styles.mjs.map +1 -0
  200. package/lib/mjs/help-message/terminal-markdown.mjs +2 -0
  201. package/lib/mjs/help-message/terminal-markdown.mjs.map +1 -0
  202. package/lib/mjs/index.mjs +2 -0
  203. package/lib/mjs/index.mjs.map +1 -0
  204. package/lib/mjs/markdown/generate-markdown.mjs +2 -0
  205. package/lib/mjs/markdown/generate-markdown.mjs.map +1 -0
  206. package/lib/mjs/metadata/arguments-metadata.mjs +2 -0
  207. package/lib/mjs/metadata/arguments-metadata.mjs.map +1 -0
  208. package/lib/mjs/metadata/cli-metadata.mjs +2 -0
  209. package/lib/mjs/metadata/cli-metadata.mjs.map +1 -0
  210. package/lib/mjs/metadata/options-metadata.mjs +2 -0
  211. package/lib/mjs/metadata/options-metadata.mjs.map +1 -0
  212. package/lib/mjs/metadata/subcommands-metadata.mjs +2 -0
  213. package/lib/mjs/metadata/subcommands-metadata.mjs.map +1 -0
  214. package/lib/mjs/parse/context/cli-context-builder.mjs +2 -0
  215. package/lib/mjs/parse/context/cli-context-builder.mjs.map +1 -0
  216. package/lib/mjs/parse/context/object-context-builder.mjs +2 -0
  217. package/lib/mjs/parse/context/object-context-builder.mjs.map +1 -0
  218. package/lib/mjs/parse/parser-utilities.mjs +2 -0
  219. package/lib/mjs/parse/parser-utilities.mjs.map +1 -0
  220. package/lib/mjs/parse/safe-parse.mjs +2 -0
  221. package/lib/mjs/parse/safe-parse.mjs.map +1 -0
  222. package/lib/mjs/parse/validation/validate-context.mjs +2 -0
  223. package/lib/mjs/parse/validation/validate-context.mjs.map +1 -0
  224. package/lib/mjs/parse/validation/validators/arguments.mjs +2 -0
  225. package/lib/mjs/parse/validation/validators/arguments.mjs.map +1 -0
  226. package/lib/mjs/parse/validation/validators/conflict.mjs +2 -0
  227. package/lib/mjs/parse/validation/validators/conflict.mjs.map +1 -0
  228. package/lib/mjs/parse/validation/validators/exclusive.mjs +2 -0
  229. package/lib/mjs/parse/validation/validators/exclusive.mjs.map +1 -0
  230. package/lib/mjs/parse/validation/validators/explicitly-passed.mjs +2 -0
  231. package/lib/mjs/parse/validation/validators/explicitly-passed.mjs.map +1 -0
  232. package/lib/mjs/parse/validation/validators/options.mjs +2 -0
  233. package/lib/mjs/parse/validation/validators/options.mjs.map +1 -0
  234. package/lib/mjs/parse/validation/validators/requires.mjs +2 -0
  235. package/lib/mjs/parse/validation/validators/requires.mjs.map +1 -0
  236. package/lib/mjs/utilities.mjs +2 -0
  237. package/lib/mjs/utilities.mjs.map +1 -0
  238. package/lib/typescript/autocomplete-scripts/bash-autocomplete-script.d.ts +2 -2
  239. package/lib/typescript/autocomplete-scripts/bash-autocomplete-script.d.ts.map +1 -1
  240. package/lib/typescript/autocomplete-scripts/powershell-autocomplete-script.d.ts +2 -2
  241. package/lib/typescript/autocomplete-scripts/powershell-autocomplete-script.d.ts.map +1 -1
  242. package/lib/typescript/autocomplete-scripts/zsh-autocomplete-script.d.ts +2 -2
  243. package/lib/typescript/autocomplete-scripts/zsh-autocomplete-script.d.ts.map +1 -1
  244. package/lib/typescript/coerce/coerce-methods.d.ts +20 -0
  245. package/lib/typescript/coerce/coerce-methods.d.ts.map +1 -0
  246. package/lib/typescript/coerce/string-to-array.d.ts +6 -0
  247. package/lib/typescript/coerce/string-to-array.d.ts.map +1 -0
  248. package/lib/typescript/coerce/string-to-primitive.d.ts +5 -0
  249. package/lib/typescript/coerce/string-to-primitive.d.ts.map +1 -0
  250. package/lib/typescript/coerce/string-to-set.d.ts +6 -0
  251. package/lib/typescript/coerce/string-to-set.d.ts.map +1 -0
  252. package/lib/typescript/definitions/define-arguments.d.ts +7 -0
  253. package/lib/typescript/definitions/define-arguments.d.ts.map +1 -0
  254. package/lib/typescript/definitions/define-cli.d.ts +24 -0
  255. package/lib/typescript/definitions/define-cli.d.ts.map +1 -0
  256. package/lib/typescript/definitions/define-options.d.ts +7 -0
  257. package/lib/typescript/definitions/define-options.d.ts.map +1 -0
  258. package/lib/typescript/definitions/define-subcommand.d.ts +17 -0
  259. package/lib/typescript/definitions/define-subcommand.d.ts.map +1 -0
  260. package/lib/typescript/definitions/validate-cli-definition.d.ts +4 -0
  261. package/lib/typescript/definitions/validate-cli-definition.d.ts.map +1 -0
  262. package/lib/typescript/help-message/format-arguments.d.ts +3 -3
  263. package/lib/typescript/help-message/format-arguments.d.ts.map +1 -1
  264. package/lib/typescript/help-message/format-options.d.ts +3 -3
  265. package/lib/typescript/help-message/format-options.d.ts.map +1 -1
  266. package/lib/typescript/help-message/format-subcommands.d.ts +3 -3
  267. package/lib/typescript/help-message/format-subcommands.d.ts.map +1 -1
  268. package/lib/typescript/help-message/generate-for-cli.d.ts +8 -0
  269. package/lib/typescript/help-message/generate-for-cli.d.ts.map +1 -0
  270. package/lib/typescript/help-message/generate-for-subcommand.d.ts +4 -0
  271. package/lib/typescript/help-message/generate-for-subcommand.d.ts.map +1 -0
  272. package/lib/typescript/help-message/print-help.d.ts +5 -0
  273. package/lib/typescript/help-message/print-help.d.ts.map +1 -0
  274. package/lib/typescript/help-message/set-defaults.d.ts +4 -0
  275. package/lib/typescript/help-message/set-defaults.d.ts.map +1 -0
  276. package/lib/typescript/help-message/styles.d.ts +30 -106
  277. package/lib/typescript/help-message/styles.d.ts.map +1 -1
  278. package/lib/typescript/help-message/terminal-markdown.d.ts +3 -0
  279. package/lib/typescript/help-message/terminal-markdown.d.ts.map +1 -0
  280. package/lib/typescript/index.d.ts +23 -35
  281. package/lib/typescript/index.d.ts.map +1 -1
  282. package/lib/typescript/markdown/generate-markdown.d.ts +2 -2
  283. package/lib/typescript/markdown/generate-markdown.d.ts.map +1 -1
  284. package/lib/typescript/metadata/arguments-metadata.d.ts +4 -0
  285. package/lib/typescript/metadata/arguments-metadata.d.ts.map +1 -0
  286. package/lib/typescript/metadata/cli-metadata.d.ts +4 -0
  287. package/lib/typescript/metadata/cli-metadata.d.ts.map +1 -0
  288. package/lib/typescript/metadata/options-metadata.d.ts +4 -0
  289. package/lib/typescript/metadata/options-metadata.d.ts.map +1 -0
  290. package/lib/typescript/metadata/subcommands-metadata.d.ts +4 -0
  291. package/lib/typescript/metadata/subcommands-metadata.d.ts.map +1 -0
  292. package/lib/typescript/parse/context/cli-context-builder.d.ts +9 -0
  293. package/lib/typescript/parse/context/cli-context-builder.d.ts.map +1 -0
  294. package/lib/typescript/parse/context/object-context-builder.d.ts +6 -0
  295. package/lib/typescript/parse/context/object-context-builder.d.ts.map +1 -0
  296. package/lib/typescript/{parser/parse/parser-helpers.d.ts → parse/parser-utilities.d.ts} +18 -9
  297. package/lib/typescript/parse/parser-utilities.d.ts.map +1 -0
  298. package/lib/typescript/parse/safe-parse.d.ts +5 -0
  299. package/lib/typescript/parse/safe-parse.d.ts.map +1 -0
  300. package/lib/typescript/parse/validation/validate-context.d.ts +6 -0
  301. package/lib/typescript/parse/validation/validate-context.d.ts.map +1 -0
  302. package/lib/typescript/parse/validation/validators/arguments.d.ts +12 -0
  303. package/lib/typescript/parse/validation/validators/arguments.d.ts.map +1 -0
  304. package/lib/typescript/parse/validation/validators/conflict.d.ts +16 -0
  305. package/lib/typescript/parse/validation/validators/conflict.d.ts.map +1 -0
  306. package/lib/typescript/parse/validation/validators/exclusive.d.ts +16 -0
  307. package/lib/typescript/parse/validation/validators/exclusive.d.ts.map +1 -0
  308. package/lib/typescript/parse/validation/validators/explicitly-passed.d.ts +5 -0
  309. package/lib/typescript/parse/validation/validators/explicitly-passed.d.ts.map +1 -0
  310. package/lib/typescript/parse/validation/validators/options.d.ts +12 -0
  311. package/lib/typescript/parse/validation/validators/options.d.ts.map +1 -0
  312. package/lib/typescript/parse/validation/validators/requires.d.ts +18 -0
  313. package/lib/typescript/parse/validation/validators/requires.d.ts.map +1 -0
  314. package/lib/typescript/types/context-types.d.ts +135 -0
  315. package/lib/typescript/types/context-types.d.ts.map +1 -0
  316. package/lib/typescript/types/definitions-types.d.ts +294 -0
  317. package/lib/typescript/types/definitions-types.d.ts.map +1 -0
  318. package/lib/typescript/types/help-message-types.d.ts +134 -0
  319. package/lib/typescript/types/help-message-types.d.ts.map +1 -0
  320. package/lib/typescript/types/io-types.d.ts +96 -0
  321. package/lib/typescript/types/io-types.d.ts.map +1 -0
  322. package/lib/typescript/types/metadata-types.d.ts +75 -0
  323. package/lib/typescript/types/metadata-types.d.ts.map +1 -0
  324. package/lib/typescript/types/schema-types.d.ts +6 -0
  325. package/lib/typescript/types/schema-types.d.ts.map +1 -0
  326. package/lib/typescript/types/types.d.ts +61 -0
  327. package/lib/typescript/types/types.d.ts.map +1 -0
  328. package/lib/typescript/types/utilities-types.d.ts +17 -0
  329. package/lib/typescript/types/utilities-types.d.ts.map +1 -0
  330. package/lib/typescript/utilities.d.ts +24 -10
  331. package/lib/typescript/utilities.d.ts.map +1 -1
  332. package/package.json +29 -26
  333. package/src/autocomplete-scripts/bash-autocomplete-script.ts +13 -9
  334. package/src/autocomplete-scripts/powershell-autocomplete-script.ts +21 -13
  335. package/src/autocomplete-scripts/zsh-autocomplete-script.ts +27 -23
  336. package/src/coerce/coerce-methods.ts +75 -0
  337. package/src/coerce/string-to-array.ts +18 -0
  338. package/src/coerce/string-to-primitive.ts +31 -0
  339. package/src/coerce/string-to-set.ts +15 -0
  340. package/src/definitions/define-arguments.ts +10 -0
  341. package/src/definitions/define-cli.ts +105 -0
  342. package/src/definitions/define-options.ts +12 -0
  343. package/src/definitions/define-subcommand.ts +57 -0
  344. package/src/definitions/validate-cli-definition.ts +331 -0
  345. package/src/help-message/format-arguments.ts +57 -33
  346. package/src/help-message/format-options.ts +59 -34
  347. package/src/help-message/format-subcommands.ts +43 -21
  348. package/src/help-message/generate-for-cli.ts +114 -0
  349. package/src/help-message/generate-for-subcommand.ts +32 -0
  350. package/src/help-message/print-help.ts +13 -0
  351. package/src/help-message/set-defaults.ts +34 -0
  352. package/src/help-message/styles.ts +148 -103
  353. package/src/help-message/terminal-markdown.ts +147 -0
  354. package/src/index.ts +28 -97
  355. package/src/markdown/generate-markdown.ts +47 -58
  356. package/src/metadata/arguments-metadata.ts +28 -0
  357. package/src/metadata/cli-metadata.ts +26 -0
  358. package/src/metadata/options-metadata.ts +38 -0
  359. package/src/metadata/subcommands-metadata.ts +35 -0
  360. package/src/parse/context/cli-context-builder.ts +246 -0
  361. package/src/parse/context/object-context-builder.ts +63 -0
  362. package/src/{parser/parse/parser-helpers.ts → parse/parser-utilities.ts} +46 -25
  363. package/src/parse/safe-parse.ts +76 -0
  364. package/src/parse/validation/validate-context.ts +23 -0
  365. package/src/parse/validation/validators/arguments.ts +59 -0
  366. package/src/parse/validation/validators/conflict.ts +68 -0
  367. package/src/parse/validation/validators/exclusive.ts +70 -0
  368. package/src/parse/validation/validators/explicitly-passed.ts +15 -0
  369. package/src/parse/validation/validators/options.ts +59 -0
  370. package/src/parse/validation/validators/requires.ts +82 -0
  371. package/src/types/context-types.ts +171 -0
  372. package/src/types/definitions-types.ts +340 -0
  373. package/src/types/help-message-types.ts +153 -0
  374. package/src/types/io-types.ts +131 -0
  375. package/src/types/metadata-types.ts +104 -0
  376. package/src/types/schema-types.ts +9 -0
  377. package/src/types/types.ts +72 -0
  378. package/src/types/utilities-types.ts +26 -0
  379. package/src/utilities.ts +200 -23
  380. package/lib/commonjs/autocomplete-scripts/bash-autocomplete-script.cjs +0 -42
  381. package/lib/commonjs/autocomplete-scripts/bash-autocomplete-script.cjs.map +0 -1
  382. package/lib/commonjs/autocomplete-scripts/powershell-autocomplete-script.cjs +0 -31
  383. package/lib/commonjs/autocomplete-scripts/powershell-autocomplete-script.cjs.map +0 -1
  384. package/lib/commonjs/autocomplete-scripts/zsh-autocomplete-script.cjs +0 -41
  385. package/lib/commonjs/autocomplete-scripts/zsh-autocomplete-script.cjs.map +0 -1
  386. package/lib/commonjs/help-message/format-arguments.cjs +0 -1
  387. package/lib/commonjs/help-message/format-arguments.cjs.map +0 -1
  388. package/lib/commonjs/help-message/format-cli.cjs +0 -1
  389. package/lib/commonjs/help-message/format-cli.cjs.map +0 -1
  390. package/lib/commonjs/help-message/format-options.cjs +0 -1
  391. package/lib/commonjs/help-message/format-options.cjs.map +0 -1
  392. package/lib/commonjs/help-message/format-subcommands.cjs +0 -1
  393. package/lib/commonjs/help-message/format-subcommands.cjs.map +0 -1
  394. package/lib/commonjs/help-message/styles.cjs +0 -1
  395. package/lib/commonjs/help-message/styles.cjs.map +0 -1
  396. package/lib/commonjs/index.cjs +0 -1
  397. package/lib/commonjs/index.cjs.map +0 -1
  398. package/lib/commonjs/markdown/generate-markdown.cjs +0 -1
  399. package/lib/commonjs/markdown/generate-markdown.cjs.map +0 -1
  400. package/lib/commonjs/metadata/get-arguments-metadata.cjs +0 -1
  401. package/lib/commonjs/metadata/get-arguments-metadata.cjs.map +0 -1
  402. package/lib/commonjs/metadata/get-cli-metadata.cjs +0 -1
  403. package/lib/commonjs/metadata/get-cli-metadata.cjs.map +0 -1
  404. package/lib/commonjs/metadata/get-options-metadata.cjs +0 -1
  405. package/lib/commonjs/metadata/get-options-metadata.cjs.map +0 -1
  406. package/lib/commonjs/metadata/get-subcommands-metadata.cjs +0 -1
  407. package/lib/commonjs/metadata/get-subcommands-metadata.cjs.map +0 -1
  408. package/lib/commonjs/parser/parse/parse.cjs +0 -1
  409. package/lib/commonjs/parser/parse/parse.cjs.map +0 -1
  410. package/lib/commonjs/parser/parse/parser-helpers.cjs +0 -1
  411. package/lib/commonjs/parser/parse/parser-helpers.cjs.map +0 -1
  412. package/lib/commonjs/parser/safe-parse.cjs +0 -1
  413. package/lib/commonjs/parser/safe-parse.cjs.map +0 -1
  414. package/lib/commonjs/parser/unsafe-parse.cjs +0 -1
  415. package/lib/commonjs/parser/unsafe-parse.cjs.map +0 -1
  416. package/lib/commonjs/parser/validate/validate-type.cjs +0 -1
  417. package/lib/commonjs/parser/validate/validate-type.cjs.map +0 -1
  418. package/lib/commonjs/parser/validate/validate.cjs +0 -1
  419. package/lib/commonjs/parser/validate/validate.cjs.map +0 -1
  420. package/lib/commonjs/utilities.cjs +0 -1
  421. package/lib/commonjs/utilities.cjs.map +0 -1
  422. package/lib/commonjs/zod-utilities.cjs +0 -1
  423. package/lib/commonjs/zod-utilities.cjs.map +0 -1
  424. package/lib/module/autocomplete-scripts/bash-autocomplete-script.mjs +0 -42
  425. package/lib/module/autocomplete-scripts/bash-autocomplete-script.mjs.map +0 -1
  426. package/lib/module/autocomplete-scripts/powershell-autocomplete-script.mjs +0 -31
  427. package/lib/module/autocomplete-scripts/powershell-autocomplete-script.mjs.map +0 -1
  428. package/lib/module/autocomplete-scripts/zsh-autocomplete-script.mjs +0 -41
  429. package/lib/module/autocomplete-scripts/zsh-autocomplete-script.mjs.map +0 -1
  430. package/lib/module/help-message/format-arguments.mjs +0 -1
  431. package/lib/module/help-message/format-arguments.mjs.map +0 -1
  432. package/lib/module/help-message/format-cli.mjs +0 -1
  433. package/lib/module/help-message/format-cli.mjs.map +0 -1
  434. package/lib/module/help-message/format-options.mjs +0 -1
  435. package/lib/module/help-message/format-options.mjs.map +0 -1
  436. package/lib/module/help-message/format-subcommands.mjs +0 -1
  437. package/lib/module/help-message/format-subcommands.mjs.map +0 -1
  438. package/lib/module/help-message/styles.mjs +0 -1
  439. package/lib/module/help-message/styles.mjs.map +0 -1
  440. package/lib/module/index.mjs +0 -1
  441. package/lib/module/index.mjs.map +0 -1
  442. package/lib/module/markdown/generate-markdown.mjs +0 -1
  443. package/lib/module/markdown/generate-markdown.mjs.map +0 -1
  444. package/lib/module/metadata/get-arguments-metadata.mjs +0 -1
  445. package/lib/module/metadata/get-arguments-metadata.mjs.map +0 -1
  446. package/lib/module/metadata/get-cli-metadata.mjs +0 -1
  447. package/lib/module/metadata/get-cli-metadata.mjs.map +0 -1
  448. package/lib/module/metadata/get-options-metadata.mjs +0 -1
  449. package/lib/module/metadata/get-options-metadata.mjs.map +0 -1
  450. package/lib/module/metadata/get-subcommands-metadata.mjs +0 -1
  451. package/lib/module/metadata/get-subcommands-metadata.mjs.map +0 -1
  452. package/lib/module/parser/parse/parse.mjs +0 -1
  453. package/lib/module/parser/parse/parse.mjs.map +0 -1
  454. package/lib/module/parser/parse/parser-helpers.mjs +0 -1
  455. package/lib/module/parser/parse/parser-helpers.mjs.map +0 -1
  456. package/lib/module/parser/safe-parse.mjs +0 -1
  457. package/lib/module/parser/safe-parse.mjs.map +0 -1
  458. package/lib/module/parser/unsafe-parse.mjs +0 -1
  459. package/lib/module/parser/unsafe-parse.mjs.map +0 -1
  460. package/lib/module/parser/validate/validate-type.mjs +0 -1
  461. package/lib/module/parser/validate/validate-type.mjs.map +0 -1
  462. package/lib/module/parser/validate/validate.mjs +0 -1
  463. package/lib/module/parser/validate/validate.mjs.map +0 -1
  464. package/lib/module/utilities.mjs +0 -1
  465. package/lib/module/utilities.mjs.map +0 -1
  466. package/lib/module/zod-utilities.mjs +0 -1
  467. package/lib/module/zod-utilities.mjs.map +0 -1
  468. package/lib/typescript/help-message/format-cli.d.ts +0 -6
  469. package/lib/typescript/help-message/format-cli.d.ts.map +0 -1
  470. package/lib/typescript/metadata/get-arguments-metadata.d.ts +0 -4
  471. package/lib/typescript/metadata/get-arguments-metadata.d.ts.map +0 -1
  472. package/lib/typescript/metadata/get-cli-metadata.d.ts +0 -4
  473. package/lib/typescript/metadata/get-cli-metadata.d.ts.map +0 -1
  474. package/lib/typescript/metadata/get-options-metadata.d.ts +0 -4
  475. package/lib/typescript/metadata/get-options-metadata.d.ts.map +0 -1
  476. package/lib/typescript/metadata/get-subcommands-metadata.d.ts +0 -4
  477. package/lib/typescript/metadata/get-subcommands-metadata.d.ts.map +0 -1
  478. package/lib/typescript/metadata/metadata-types.d.ts +0 -80
  479. package/lib/typescript/metadata/metadata-types.d.ts.map +0 -1
  480. package/lib/typescript/parser/parse/parse-types.d.ts +0 -85
  481. package/lib/typescript/parser/parse/parse-types.d.ts.map +0 -1
  482. package/lib/typescript/parser/parse/parse.d.ts +0 -4
  483. package/lib/typescript/parser/parse/parse.d.ts.map +0 -1
  484. package/lib/typescript/parser/parse/parser-helpers.d.ts.map +0 -1
  485. package/lib/typescript/parser/safe-parse.d.ts +0 -4
  486. package/lib/typescript/parser/safe-parse.d.ts.map +0 -1
  487. package/lib/typescript/parser/unsafe-parse.d.ts +0 -4
  488. package/lib/typescript/parser/unsafe-parse.d.ts.map +0 -1
  489. package/lib/typescript/parser/validate/validate-type.d.ts +0 -23
  490. package/lib/typescript/parser/validate/validate-type.d.ts.map +0 -1
  491. package/lib/typescript/parser/validate/validate.d.ts +0 -12
  492. package/lib/typescript/parser/validate/validate.d.ts.map +0 -1
  493. package/lib/typescript/types.d.ts +0 -294
  494. package/lib/typescript/types.d.ts.map +0 -1
  495. package/lib/typescript/zod-utilities.d.ts +0 -28
  496. package/lib/typescript/zod-utilities.d.ts.map +0 -1
  497. package/src/help-message/format-cli.ts +0 -141
  498. package/src/metadata/get-arguments-metadata.ts +0 -25
  499. package/src/metadata/get-cli-metadata.ts +0 -23
  500. package/src/metadata/get-options-metadata.ts +0 -35
  501. package/src/metadata/get-subcommands-metadata.ts +0 -32
  502. package/src/metadata/metadata-types.ts +0 -114
  503. package/src/parser/parse/parse-types.ts +0 -89
  504. package/src/parser/parse/parse.ts +0 -235
  505. package/src/parser/safe-parse.ts +0 -103
  506. package/src/parser/unsafe-parse.ts +0 -98
  507. package/src/parser/validate/validate-type.ts +0 -20
  508. package/src/parser/validate/validate.ts +0 -71
  509. package/src/types.ts +0 -365
  510. package/src/zod-utilities.ts +0 -214
@@ -0,0 +1,75 @@
1
+ import { stringToBooleanArray, stringToNumberArray, stringToStringArray } from "./string-to-array.ts";
2
+ import { stringToBoolean, stringToNumber } from "./string-to-primitive.ts";
3
+ import { stringToBooleanSet, stringToNumberSet, stringToStringSet } from "./string-to-set.ts";
4
+
5
+ import type { CoerceMethod } from "../types/types.ts";
6
+
7
+ const string: CoerceMethod<string> = terminalInput => terminalInput;
8
+ string.type = "string";
9
+
10
+ const boolean: CoerceMethod<boolean> = terminalInput => stringToBoolean(terminalInput);
11
+ boolean.type = "boolean";
12
+
13
+ const number: CoerceMethod<number> = terminalInput => stringToNumber(terminalInput);
14
+ number.type = "number";
15
+
16
+ const json = <T>(reviver?: (this: any, key: string, value: any) => any): CoerceMethod<T> => {
17
+ const coerceMethod: CoerceMethod<T> = terminalInput => JSON.parse(terminalInput, reviver) as T;
18
+ coerceMethod.type = "unknown";
19
+ return coerceMethod;
20
+ };
21
+
22
+ const stringArray = (separator: string): CoerceMethod<string[]> => {
23
+ const coerceMethod: CoerceMethod<string[]> = terminalInput => stringToStringArray(terminalInput, separator);
24
+ coerceMethod.type = "string[]";
25
+ return coerceMethod;
26
+ };
27
+
28
+ const numberArray = (separator: string) => {
29
+ const coerceMethod: CoerceMethod<number[]> = terminalInput => stringToNumberArray(terminalInput, separator);
30
+ coerceMethod.type = "number[]";
31
+ return coerceMethod;
32
+ };
33
+
34
+ const booleanArray = (separator: string) => {
35
+ const coerceMethod: CoerceMethod<boolean[]> = terminalInput => stringToBooleanArray(terminalInput, separator);
36
+ coerceMethod.type = "boolean[]";
37
+ return coerceMethod;
38
+ };
39
+
40
+ const stringSet = (separator: string) => {
41
+ const coerceMethod: CoerceMethod<Set<string>> = terminalInput => stringToStringSet(terminalInput, separator);
42
+ coerceMethod.type = "set<string>";
43
+ return coerceMethod;
44
+ };
45
+
46
+ const numberSet = (separator: string) => {
47
+ const coerceMethod: CoerceMethod<Set<number>> = terminalInput => stringToNumberSet(terminalInput, separator);
48
+ coerceMethod.type = "set<number>";
49
+ return coerceMethod;
50
+ };
51
+
52
+ const booleanSet = (separator: string) => {
53
+ const coerceMethod: CoerceMethod<Set<boolean>> = terminalInput => stringToBooleanSet(terminalInput, separator);
54
+ coerceMethod.type = "set<boolean>";
55
+ return coerceMethod;
56
+ };
57
+
58
+ export const coerce = {
59
+ string,
60
+ boolean,
61
+ number,
62
+ /** @param separator - The separator to use to split the string. **Default** is `","` */
63
+ stringArray,
64
+ /** @param separator - The separator to use to split the string. **Default** is `","` */
65
+ numberArray,
66
+ /** @param separator - The separator to use to split the string. **Default** is `","` */
67
+ booleanArray,
68
+ /** @param separator - The separator to use to split the string. **Default** is `","` */
69
+ stringSet,
70
+ /** @param separator - The separator to use to split the string. **Default** is `","` */
71
+ numberSet,
72
+ /** @param separator - The separator to use to split the string. **Default** is `","` */
73
+ booleanSet,
74
+ json,
75
+ };
@@ -0,0 +1,18 @@
1
+ import { stringToBoolean, stringToNumber } from "./string-to-primitive.ts";
2
+
3
+ export function stringToStringArray(stringValue: string, separator: string = ","): string[] {
4
+ return stringValue
5
+ .split(separator)
6
+ .map(s => s.trim())
7
+ .filter(Boolean);
8
+ }
9
+
10
+ /** @throws {TypeError} - Because of `stringToNumber` */
11
+ export function stringToNumberArray(stringValue: string, separator: string = ","): number[] {
12
+ return stringToStringArray(stringValue, separator).map(element => stringToNumber(element));
13
+ }
14
+
15
+ /** @throws {TypeError} - Because of `stringToBoolean` */
16
+ export function stringToBooleanArray(stringValue: string, separator: string = ","): boolean[] {
17
+ return stringToStringArray(stringValue, separator).map(element => stringToBoolean(element));
18
+ }
@@ -0,0 +1,31 @@
1
+ /** @throws {TypeError} */
2
+ export function stringToBoolean(string: string): boolean {
3
+ if (string.toLowerCase() === "true") {
4
+ return true;
5
+ }
6
+
7
+ if (string.toLowerCase() === "false") {
8
+ return false;
9
+ }
10
+
11
+ throw new TypeError(`Invalid boolean value: ${string}`);
12
+ }
13
+
14
+ /** @throws {TypeError} */
15
+ export function stringToNumber(string: string): number {
16
+ const trimmed = string.trim();
17
+
18
+ // Reject empty, whitespace-only, or signs without digits
19
+ if (trimmed === "" || trimmed === "+" || trimmed === "-") {
20
+ throw new TypeError(`Invalid number: "${string}"`);
21
+ }
22
+
23
+ const result = Number(trimmed);
24
+
25
+ // Reject NaN, Infinity, and -Infinity
26
+ if (!Number.isFinite(result)) {
27
+ throw new TypeError(`Invalid number: "${string}"`);
28
+ }
29
+
30
+ return result;
31
+ }
@@ -0,0 +1,15 @@
1
+ import { stringToBooleanArray, stringToNumberArray, stringToStringArray } from "./string-to-array.ts";
2
+
3
+ export function stringToStringSet(stringValue: string, separator: string = ","): Set<string> {
4
+ return new Set(stringToStringArray(stringValue, separator));
5
+ }
6
+
7
+ /** @throws {TypeError} - Because of `stringToNumber` */
8
+ export function stringToNumberSet(stringValue: string, separator: string = ","): Set<number> {
9
+ return new Set(stringToNumberArray(stringValue, separator));
10
+ }
11
+
12
+ /** @throws {TypeError} - Because of `stringToBoolean` */
13
+ export function stringToBooleanSet(stringValue: string, separator: string = ","): Set<boolean> {
14
+ return new Set(stringToBooleanArray(stringValue, separator));
15
+ }
@@ -0,0 +1,10 @@
1
+ import { prepareDefinitionTypes } from "../utilities.ts";
2
+
3
+ import type { Argument } from "../types/definitions-types.ts";
4
+
5
+ export function defineArguments<const T extends Record<string, Argument>>(arguments_: {
6
+ [K in keyof T]: T[K] & Argument<T[K]["schema"]>;
7
+ }): { [K in keyof T]: Argument<T[K]["schema"]> } {
8
+ prepareDefinitionTypes(arguments_);
9
+ return arguments_;
10
+ }
@@ -0,0 +1,105 @@
1
+ import { generateCliHelpMessage } from "../help-message/generate-for-cli.ts";
2
+ import { generateSubcommandHelpMessage } from "../help-message/generate-for-subcommand.ts";
3
+ import { buildObjectContext } from "../parse/context/object-context-builder.ts";
4
+ import { safeParse, safeParseAsync } from "../parse/safe-parse.ts";
5
+ import { validate } from "../parse/validation/validate-context.ts";
6
+ import { prepareDefinitionTypes } from "../utilities.ts";
7
+
8
+ import type { Argument, Cli, Option, Subcommand } from "../types/definitions-types.ts";
9
+ import type { PrintHelpOptions } from "../types/help-message-types.ts";
10
+ import type { AttachedMethods, AttachedMethodsWide, ValidateMethods } from "../types/types.ts";
11
+ import type { Prettify } from "../types/utilities-types.ts";
12
+
13
+ type OptionsInput<T> =
14
+ T extends Record<string, Option> ? { [OptionName in keyof T]: Option<T[OptionName]["schema"]> } : T;
15
+
16
+ type ArgumentsInput<T> =
17
+ T extends Record<string, Argument> ? { [ArgumentName in keyof T]: Argument<T[ArgumentName]["schema"]> } : T;
18
+
19
+ type SubcommandsInput<T extends readonly [Subcommand, ...Subcommand[]]> = {
20
+ [SubcommandIndex in keyof T]: {
21
+ [K in keyof T[SubcommandIndex]]: T[SubcommandIndex][K] extends Record<string, Option>
22
+ ? OptionsInput<T[SubcommandIndex][K]>
23
+ : T[SubcommandIndex][K] extends Record<string, Argument>
24
+ ? ArgumentsInput<T[SubcommandIndex][K]>
25
+ : T[SubcommandIndex][K];
26
+ } & Subcommand;
27
+ };
28
+
29
+ // This will prevent extra keys and enable jsdoc on hover
30
+ type CliInput<T extends Cli> = {
31
+ [K in keyof T]: K extends keyof Cli
32
+ ? T[K] extends readonly [Subcommand, ...Subcommand[]]
33
+ ? SubcommandsInput<T[K]>
34
+ : K extends "options"
35
+ ? OptionsInput<T[K]>
36
+ : K extends "arguments"
37
+ ? ArgumentsInput<T[K]>
38
+ : T[K]
39
+ : never;
40
+ };
41
+
42
+ export function defineCLI<T extends Cli>(input: CliInput<T> & Cli) {
43
+ const cliSchema = input as Prettify<T & AttachedMethods<T> & ValidateMethods<T>>;
44
+
45
+ prepareDefinitionTypes(cliSchema.options);
46
+ prepareDefinitionTypes(cliSchema.arguments);
47
+
48
+ if (cliSchema.subcommands) {
49
+ for (const subcommand of Object.values(cliSchema.subcommands)) {
50
+ prepareDefinitionTypes(subcommand.options);
51
+ prepareDefinitionTypes(subcommand.arguments);
52
+ }
53
+ }
54
+
55
+ const onExecute = (handler: (Cli["_onExecute"] & {})[number]) => {
56
+ cliSchema._onExecute ??= [];
57
+ cliSchema._onExecute.push(handler);
58
+
59
+ return () => {
60
+ const handlerIndex = cliSchema._onExecute?.indexOf(handler);
61
+ if (!handlerIndex || handlerIndex < 0) return;
62
+ cliSchema._onExecute?.splice(handlerIndex, 1);
63
+ };
64
+ };
65
+
66
+ const execute: AttachedMethodsWide["execute"] = inputValues => {
67
+ inputValues ??= {};
68
+ if (!cliSchema._onExecute) throw new Error("Action is not defined");
69
+ const context = buildObjectContext(inputValues, cliSchema);
70
+ const validateResult = validate(context, cliSchema);
71
+
72
+ if (cliSchema._onExecute) {
73
+ for (const handler of cliSchema._onExecute) {
74
+ handler(validateResult);
75
+ }
76
+ }
77
+ };
78
+
79
+ // Add print methods for CLI schema and its subcommands
80
+ const generateHelpMethods: Pick<AttachedMethodsWide, "generateCliHelpMessage" | "generateSubcommandHelpMessage"> = {
81
+ generateCliHelpMessage(options?: PrintHelpOptions) {
82
+ return generateCliHelpMessage(cliSchema, options);
83
+ },
84
+ generateSubcommandHelpMessage(subcommandName: string, options?: PrintHelpOptions) {
85
+ const foundSubcommand = cliSchema.subcommands?.find(s => s.name === subcommandName);
86
+ if (!foundSubcommand) throw new Error(`Subcommand ${subcommandName} not found`);
87
+ return generateSubcommandHelpMessage(foundSubcommand, options, cliSchema.cliName);
88
+ },
89
+ };
90
+
91
+ Object.assign(cliSchema, generateHelpMethods);
92
+
93
+ if (cliSchema.subcommands) {
94
+ for (const subcommandSchema of cliSchema.subcommands) {
95
+ Object.assign(subcommandSchema, generateHelpMethods);
96
+ }
97
+ }
98
+
99
+ return Object.assign(cliSchema, {
100
+ execute,
101
+ onExecute,
102
+ run: (stringOrArgv: string | string[]) => safeParse(stringOrArgv, cliSchema),
103
+ runAsync: (stringOrArgv: string | string[]) => safeParseAsync(stringOrArgv, cliSchema),
104
+ });
105
+ }
@@ -0,0 +1,12 @@
1
+ import { prepareDefinitionTypes } from "../utilities.ts";
2
+
3
+ import type { Option } from "../types/definitions-types.ts";
4
+
5
+ export function defineOptions<T extends Record<string, Option>>(options: {
6
+ [K in keyof T]: T[K] & Option<T[K]["schema"]>;
7
+ }): {
8
+ [K in keyof T]: Option<T[K]["schema"]>;
9
+ } {
10
+ prepareDefinitionTypes(options);
11
+ return options;
12
+ }
@@ -0,0 +1,57 @@
1
+ import { buildObjectContext } from "../parse/context/object-context-builder.ts";
2
+ import { validate } from "../parse/validation/validate-context.ts";
3
+ import { prepareDefinitionTypes } from "../utilities.ts";
4
+
5
+ import type { Argument, Option, Subcommand } from "../types/definitions-types.ts";
6
+ import type { AttachedMethods, AttachedMethodsWide } from "../types/types.ts";
7
+ import type { Prettify } from "../types/utilities-types.ts";
8
+
9
+ type OptionsInput<T> =
10
+ T extends Record<string, Option> ? { [OptionName in keyof T]: Option<T[OptionName]["schema"]> } : T;
11
+
12
+ type ArgumentsInput<T> =
13
+ T extends Record<string, Argument> ? { [ArgumentName in keyof T]: Argument<T[ArgumentName]["schema"]> } : T;
14
+
15
+ // This will prevent extra keys and enable jsdoc on hover
16
+ type SubcommandInput<T extends Subcommand> = {
17
+ [K in keyof T]: K extends keyof Subcommand
18
+ ? K extends "options"
19
+ ? OptionsInput<T[K]>
20
+ : K extends "arguments"
21
+ ? ArgumentsInput<T[K]>
22
+ : T[K]
23
+ : never;
24
+ };
25
+
26
+ export function defineSubcommand<T extends Subcommand>(input: SubcommandInput<T> & Subcommand) {
27
+ const subcommandSchema = input as Prettify<T & AttachedMethods<T>>;
28
+
29
+ prepareDefinitionTypes(subcommandSchema.options);
30
+ prepareDefinitionTypes(subcommandSchema.arguments);
31
+
32
+ const onExecute = (handler: (Subcommand["_onExecute"] & {})[number]) => {
33
+ subcommandSchema._onExecute ??= [];
34
+ subcommandSchema._onExecute.push(handler);
35
+
36
+ return () => {
37
+ const handlerIndex = subcommandSchema._onExecute?.indexOf(handler);
38
+ if (!handlerIndex || handlerIndex < 0) return;
39
+ subcommandSchema._onExecute?.splice(handlerIndex, 1);
40
+ };
41
+ };
42
+
43
+ const execute: AttachedMethodsWide["execute"] = inputValues => {
44
+ inputValues ??= {};
45
+ if (!subcommandSchema._onExecute) throw new Error("Action is not defined");
46
+ const context = buildObjectContext(inputValues, subcommandSchema);
47
+ const validateResult = validate(context, subcommandSchema);
48
+
49
+ if (subcommandSchema._onExecute) {
50
+ for (const handler of subcommandSchema._onExecute) {
51
+ handler(validateResult);
52
+ }
53
+ }
54
+ };
55
+
56
+ return Object.assign(subcommandSchema, { onExecute, execute });
57
+ }
@@ -0,0 +1,331 @@
1
+ import { transformOptionToArgument } from "../parse/parser-utilities.ts";
2
+ import { findDuplicateStrings } from "../utilities.ts";
3
+
4
+ import type { Cli, Subcommand } from "../types/definitions-types.ts";
5
+
6
+ /** @throws {Error} If validation fails. */
7
+ export function validateCliDefinition(cliDefinition: Cli) {
8
+ if (!cliDefinition.cliName) {
9
+ throw new Error(`invalid cli definition: "cliName" property is required.`);
10
+ }
11
+
12
+ // validate cli options
13
+ validateOptions(cliDefinition);
14
+
15
+ // validate cli arguments
16
+ validateArguments(cliDefinition);
17
+
18
+ const subcommands = cliDefinition.subcommands;
19
+ if (!subcommands) return; // ok
20
+
21
+ // no empty subcommands array
22
+ if (subcommands.length === 0) {
23
+ throw new Error(
24
+ `invalid cli definition "${cliDefinition.cliName}": "subcommands" property is optional but cannot be empty.`,
25
+ );
26
+ }
27
+
28
+ const commandsNames = subcommands.map(c => c.name);
29
+
30
+ // required subcommand name
31
+ if (commandsNames.some(c => !c)) {
32
+ throw new Error(`invalid subcommand definition: subcommand's "name" property is required.`);
33
+ }
34
+
35
+ // no duplicate subcommand names
36
+ const commandsNamesDuplicates = findDuplicateStrings(commandsNames).map(c => `"${c}"`);
37
+ if (commandsNamesDuplicates.length > 0) {
38
+ throw new Error(
39
+ `invalid cli definition "${cliDefinition.cliName}" has duplicated subcommands: ${commandsNamesDuplicates.join(", ")}.`,
40
+ );
41
+ }
42
+
43
+ for (const subcommand of subcommands) {
44
+ // command aliases check
45
+ if (subcommand.aliases) {
46
+ // no duplicated aliases
47
+ const aliasesDuplicates = findDuplicateStrings(subcommand.aliases).map(c => `"${c}"`);
48
+ if (aliasesDuplicates.length > 0) {
49
+ throw new Error(`subcommand "${subcommand.name}" has duplicated aliases: ${aliasesDuplicates.join(", ")}.`);
50
+ }
51
+
52
+ for (const alias of subcommand.aliases) {
53
+ // no empty alias
54
+ if (alias === "") {
55
+ throw new Error(`subcommand "${subcommand.name}" has an empty string alias.`);
56
+ }
57
+
58
+ // no conflict with subcommand name
59
+ if (commandsNames.includes(alias)) {
60
+ throw new Error(`subcommand "${subcommand.name}" alias "${alias}" conflicts with another subcommand name.`);
61
+ }
62
+
63
+ // no conflict with another alias
64
+ const aliasConflicts = subcommands.filter(c => c.name !== subcommand.name && c.aliases?.includes(alias));
65
+ if (aliasConflicts.length > 0) {
66
+ throw new Error(
67
+ `subcommand "${subcommand.name}" alias "${alias}" conflicts with another subcommand alias: "${aliasConflicts[0].name}".`,
68
+ );
69
+ }
70
+ }
71
+ }
72
+
73
+ // validate subcommand options
74
+ validateOptions(subcommand);
75
+
76
+ // validate subcommand arguments
77
+ validateArguments(subcommand);
78
+ }
79
+ }
80
+
81
+ function validateOptions(commandDefinition: Cli | Subcommand) {
82
+ if (!commandDefinition.options) return; // ok
83
+
84
+ const isCli = "cliName" in commandDefinition;
85
+ const name = isCli ? commandDefinition.cliName : commandDefinition.name;
86
+
87
+ const createError = (message: string) => {
88
+ return new Error(`invalid ${isCli ? "cli" : "subcommand"} definition "${name}": ${message}`);
89
+ };
90
+
91
+ const optionsDefinitionEntries = Object.entries(commandDefinition.options);
92
+
93
+ // no empty options
94
+ if (optionsDefinitionEntries.length === 0) {
95
+ throw createError(`"options" property is optional but cannot be empty.`);
96
+ }
97
+
98
+ for (const [name, option] of optionsDefinitionEntries) {
99
+ // required type
100
+ if (!option.schema) {
101
+ throw createError(`the option "${name}" missing a required property: "schema".`);
102
+ }
103
+
104
+ // should not happen
105
+ if (!option._preparedType) {
106
+ throw createError(`internal error: missing prepared type for option "${name}".`);
107
+ }
108
+
109
+ // no negated option name for boolean options
110
+ if (isNegatedOptionName(name)) {
111
+ throw createError(`the option "${name}" is a negated option name.`);
112
+ }
113
+
114
+ // no conflict with argument name
115
+ if (commandDefinition.arguments && name in commandDefinition.arguments) {
116
+ throw createError(`the option "${name}" name conflicts with an argument name.`);
117
+ }
118
+
119
+ if (option.aliases) {
120
+ // no duplicate aliases
121
+ const aliasesDuplicates = findDuplicateStrings(option.aliases);
122
+ if (aliasesDuplicates.length > 0) {
123
+ throw createError(`the option "${name}" has duplicated aliases: ${aliasesDuplicates.join(", ")}.`);
124
+ }
125
+
126
+ for (const alias of option.aliases) {
127
+ // no empty string aliases
128
+ if (alias === "") {
129
+ throw createError(`the option "${name}" has an empty string alias.`);
130
+ }
131
+
132
+ // no negated alias name for boolean options
133
+ if (isNegatedOptionName(alias)) {
134
+ throw createError(`the alias "${alias}" of the option "${name}" is a negated option name.`);
135
+ }
136
+
137
+ // no alias name should conflict with any option name
138
+ if (commandDefinition.options[alias]) {
139
+ throw createError(`the alias "${alias}" of the option "${name}" conflicts with another option name.`);
140
+ }
141
+
142
+ // no alias name should conflict with any argument name
143
+ if (commandDefinition.arguments && alias in commandDefinition.arguments) {
144
+ throw createError(`the alias "${alias}" of the option "${name}" conflicts with an argument name.`);
145
+ }
146
+
147
+ // no alias name should conflict with any other alias name
148
+ const findConflict = optionsDefinitionEntries.find(([n, d]) => n !== name && d.aliases?.includes(alias));
149
+ if (findConflict) {
150
+ throw createError(
151
+ `the alias "${alias}" of the option "${name}" conflicts with another alias name of the option "${findConflict[0]}".`,
152
+ );
153
+ }
154
+ }
155
+ }
156
+
157
+ if (option.requires) {
158
+ // no self require
159
+ if (option.requires.includes(name)) {
160
+ throw createError(`the option "${name}" cannot require itself.`);
161
+ }
162
+
163
+ // no duplicate requires
164
+ const duplicateRequires = findDuplicateStrings(option.requires).map(required => `"${required}"`);
165
+ if (duplicateRequires.length > 0) {
166
+ throw createError(`the option "${name}" has duplicate requires: ${duplicateRequires.join(", ")}.`);
167
+ }
168
+
169
+ // no unknown required name
170
+ for (const required of option.requires) {
171
+ const exits = required in commandDefinition.options || required in (commandDefinition.arguments ?? []);
172
+ if (!exits) {
173
+ throw createError(`the option "${name}" requires "${required}", but it does not exist.`);
174
+ }
175
+ }
176
+ }
177
+
178
+ if (option.conflictWith) {
179
+ // no self conflict
180
+ if (option.conflictWith.includes(name)) {
181
+ throw createError(`the option "${name}" cannot conflict itself.`);
182
+ }
183
+
184
+ // no duplicate conflicts
185
+ const duplicateRequires = findDuplicateStrings(option.conflictWith).map(conflict => `"${conflict}"`);
186
+ if (duplicateRequires.length > 0) {
187
+ throw createError(`the option "${name}" has duplicate conflicts: ${duplicateRequires.join(", ")}.`);
188
+ }
189
+
190
+ // no unknown conflict name
191
+ for (const required of option.conflictWith) {
192
+ const exits = required in commandDefinition.options || required in (commandDefinition.arguments ?? []);
193
+ if (!exits) {
194
+ throw createError(`the option "${name}" conflict with "${required}", but it does not exist.`);
195
+ }
196
+ }
197
+ }
198
+
199
+ // no intersection between requires and conflicts
200
+ if (option.requires && option.conflictWith) {
201
+ const requiresSet = new Set(option.requires);
202
+ const conflictsSet = new Set(option.conflictWith);
203
+
204
+ const intersection = requiresSet.intersection(conflictsSet);
205
+ const intersectionArray = Array.from(intersection).map(name => `"${name}"`);
206
+
207
+ if (intersectionArray.length > 0) {
208
+ const s = intersectionArray.length > 1 ? "s" : "";
209
+ throw createError(
210
+ `the option "${name}" cannot require and conflict with the same name${s}: ${intersectionArray.join(", ")}.`,
211
+ );
212
+ }
213
+ }
214
+ }
215
+ }
216
+
217
+ function validateArguments(commandDefinition: Cli | Subcommand) {
218
+ if (!commandDefinition.arguments) return; // ok
219
+
220
+ const isCli = "cliName" in commandDefinition;
221
+ const name = isCli ? commandDefinition.cliName : commandDefinition.name;
222
+
223
+ const createError = (message: string) => {
224
+ return new Error(`invalid ${isCli ? "cli" : "subcommand"} definition "${name}": ${message}`);
225
+ };
226
+
227
+ if (commandDefinition.arguments) {
228
+ const argumentsDefinitionEntries = Object.entries(commandDefinition.arguments);
229
+
230
+ // no empty arguments record
231
+ if (argumentsDefinitionEntries.length === 0) {
232
+ throw createError(`"arguments" property is optional but cannot be empty.`);
233
+ }
234
+
235
+ for (const [index, [name, argument]] of argumentsDefinitionEntries.entries()) {
236
+ // no number key name
237
+ if (/^\d+$/.test(name)) {
238
+ throw createError(`the argument "${name}" name cannot be a number.`);
239
+ }
240
+
241
+ // should not happen
242
+ if (!argument._preparedType) {
243
+ throw createError(`internal error: missing prepared type for argument "${name}".`);
244
+ }
245
+
246
+ // no missing type
247
+ if (!argument.schema) {
248
+ throw createError(`the argument "${name}" missing a required property: "schema".`);
249
+ }
250
+
251
+ // no conflicting option
252
+ if (commandDefinition.options && name in commandDefinition.options) {
253
+ throw createError(`the argument "${name}" name conflicts with an option name.`);
254
+ }
255
+
256
+ if (!argument._preparedType.optional) continue; // ok
257
+
258
+ // no optional argument when "allowPositionals" is enabled
259
+ if (commandDefinition.allowPositionals) {
260
+ throw createError(`the argument "${name}" cannot be optional when "allowPositionals" is enabled.`);
261
+ }
262
+
263
+ // only last argument can be optional
264
+ if (index !== argumentsDefinitionEntries.length - 1) {
265
+ throw createError(`the argument "${name}" cannot be optional unless it is the last argument.`);
266
+ }
267
+
268
+ if (argument.requires) {
269
+ // no self require
270
+ if (argument.requires.includes(name)) {
271
+ throw createError(`the argument "${name}" cannot require itself.`);
272
+ }
273
+
274
+ // no duplicate requires
275
+ const duplicateRequires = findDuplicateStrings(argument.requires).map(required => `"${required}"`);
276
+ if (duplicateRequires.length > 0) {
277
+ throw createError(`the argument "${name}" has duplicate requires: ${duplicateRequires.join(", ")}.`);
278
+ }
279
+
280
+ // no unknown require
281
+ for (const required of argument.requires) {
282
+ const exits = required in (commandDefinition.options ?? {}) || required in commandDefinition.arguments;
283
+ if (!exits) {
284
+ throw createError(`the argument "${name}" requires "${required}", but it does not exist.`);
285
+ }
286
+ }
287
+ }
288
+
289
+ if (argument.conflictWith) {
290
+ // no self conflict
291
+ if (argument.conflictWith.includes(name)) {
292
+ throw createError(`the argument "${name}" cannot conflict itself.`);
293
+ }
294
+
295
+ // no duplicate conflicts
296
+ const duplicateRequires = findDuplicateStrings(argument.conflictWith).map(conflict => `"${conflict}"`);
297
+ if (duplicateRequires.length > 0) {
298
+ throw createError(`the argument "${name}" has duplicate conflicts: ${duplicateRequires.join(", ")}.`);
299
+ }
300
+
301
+ // no unknown conflict
302
+ for (const required of argument.conflictWith) {
303
+ const exits = required in (commandDefinition.options ?? {}) || required in commandDefinition.arguments;
304
+ if (!exits) {
305
+ throw createError(`the argument "${name}" conflict with "${required}", but it does not exist.`);
306
+ }
307
+ }
308
+ }
309
+
310
+ // no intersection between requires and conflicts
311
+ if (argument.requires && argument.conflictWith) {
312
+ const requiresSet = new Set(argument.requires);
313
+ const conflictsSet = new Set(argument.conflictWith);
314
+
315
+ const intersection = requiresSet.intersection(conflictsSet);
316
+ const intersectionArray = Array.from(intersection).map(name => `"${name}"`);
317
+
318
+ if (intersectionArray.length > 0) {
319
+ const s = intersectionArray.length > 1 ? "s" : "";
320
+ throw createError(
321
+ `the argument "${name}" cannot require and conflict with the same name${s}: ${intersectionArray.join(", ")}.`,
322
+ );
323
+ }
324
+ }
325
+ }
326
+ }
327
+ }
328
+
329
+ function isNegatedOptionName(name: string) {
330
+ return transformOptionToArgument(name).startsWith("--no-");
331
+ }