@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.
- package/LICENSE +21 -0
- package/README.md +29 -0
- package/dist/src/__tests__/issue-163.spec.d.ts +2 -0
- package/dist/src/__tests__/issue-163.spec.d.ts.map +1 -0
- package/dist/src/__tests__/issue-163.spec.js +17 -0
- package/dist/src/__tests__/issue-163.spec.js.map +1 -0
- package/dist/src/argument/__tests__/argument.spec.d.ts +2 -0
- package/dist/src/argument/__tests__/argument.spec.d.ts.map +1 -0
- package/dist/src/argument/__tests__/argument.spec.js +85 -0
- package/dist/src/argument/__tests__/argument.spec.js.map +1 -0
- package/dist/src/argument/find.d.ts +8 -0
- package/dist/src/argument/find.d.ts.map +1 -0
- package/dist/src/argument/find.js +11 -0
- package/dist/src/argument/find.js.map +1 -0
- package/dist/src/argument/index.d.ts +13 -0
- package/dist/src/argument/index.d.ts.map +1 -0
- package/dist/src/argument/index.js +27 -0
- package/dist/src/argument/index.js.map +1 -0
- package/dist/src/argument/synopsis.d.ts +19 -0
- package/dist/src/argument/synopsis.d.ts.map +1 -0
- package/dist/src/argument/synopsis.js +39 -0
- package/dist/src/argument/synopsis.js.map +1 -0
- package/dist/src/argument/validate.d.ts +43 -0
- package/dist/src/argument/validate.d.ts.map +1 -0
- package/dist/src/argument/validate.js +127 -0
- package/dist/src/argument/validate.js.map +1 -0
- package/dist/src/autocomplete/__fixtures__/prog-autocomplete.d.ts +3 -0
- package/dist/src/autocomplete/__fixtures__/prog-autocomplete.d.ts.map +1 -0
- package/dist/src/autocomplete/__fixtures__/prog-autocomplete.js +24 -0
- package/dist/src/autocomplete/__fixtures__/prog-autocomplete.js.map +1 -0
- package/dist/src/autocomplete/__tests__/autocomplete.spec.d.ts +2 -0
- package/dist/src/autocomplete/__tests__/autocomplete.spec.d.ts.map +1 -0
- package/dist/src/autocomplete/__tests__/autocomplete.spec.js +119 -0
- package/dist/src/autocomplete/__tests__/autocomplete.spec.js.map +1 -0
- package/dist/src/autocomplete/index.d.ts +20 -0
- package/dist/src/autocomplete/index.d.ts.map +1 -0
- package/dist/src/autocomplete/index.js +172 -0
- package/dist/src/autocomplete/index.js.map +1 -0
- package/dist/src/autocomplete/types.d.ts +26 -0
- package/dist/src/autocomplete/types.d.ts.map +1 -0
- package/dist/src/autocomplete/types.js +3 -0
- package/dist/src/autocomplete/types.js.map +1 -0
- package/dist/src/command/__fixtures__/example-cmd.d.ts +8 -0
- package/dist/src/command/__fixtures__/example-cmd.d.ts.map +1 -0
- package/dist/src/command/__fixtures__/example-cmd.js +10 -0
- package/dist/src/command/__fixtures__/example-cmd.js.map +1 -0
- package/dist/src/command/__tests__/command.spec.d.ts +2 -0
- package/dist/src/command/__tests__/command.spec.d.ts.map +1 -0
- package/dist/src/command/__tests__/command.spec.js +510 -0
- package/dist/src/command/__tests__/command.spec.js.map +1 -0
- package/dist/src/command/__tests__/find.spec.d.ts +2 -0
- package/dist/src/command/__tests__/find.spec.d.ts.map +1 -0
- package/dist/src/command/__tests__/find.spec.js +31 -0
- package/dist/src/command/__tests__/find.spec.js.map +1 -0
- package/dist/src/command/__tests__/import.spec.d.ts +2 -0
- package/dist/src/command/__tests__/import.spec.d.ts.map +1 -0
- package/dist/src/command/__tests__/import.spec.js +17 -0
- package/dist/src/command/__tests__/import.spec.js.map +1 -0
- package/dist/src/command/__tests__/scan.spec.d.ts +2 -0
- package/dist/src/command/__tests__/scan.spec.d.ts.map +1 -0
- package/dist/src/command/__tests__/scan.spec.js +20 -0
- package/dist/src/command/__tests__/scan.spec.js.map +1 -0
- package/dist/src/command/find.d.ts +8 -0
- package/dist/src/command/find.d.ts.map +1 -0
- package/dist/src/command/find.js +47 -0
- package/dist/src/command/find.js.map +1 -0
- package/dist/src/command/import.d.ts +7 -0
- package/dist/src/command/import.d.ts.map +1 -0
- package/dist/src/command/import.js +47 -0
- package/dist/src/command/import.js.map +1 -0
- package/dist/src/command/index.d.ts +211 -0
- package/dist/src/command/index.d.ts.map +1 -0
- package/dist/src/command/index.js +374 -0
- package/dist/src/command/index.js.map +1 -0
- package/dist/src/command/scan.d.ts +4 -0
- package/dist/src/command/scan.d.ts.map +1 -0
- package/dist/src/command/scan.js +31 -0
- package/dist/src/command/scan.js.map +1 -0
- package/dist/src/command/validate-call.d.ts +8 -0
- package/dist/src/command/validate-call.d.ts.map +1 -0
- package/dist/src/command/validate-call.js +13 -0
- package/dist/src/command/validate-call.js.map +1 -0
- package/dist/src/config/index.d.ts +7 -0
- package/dist/src/config/index.d.ts.map +1 -0
- package/dist/src/config/index.js +24 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/error/__tests__/fatal.spec.d.ts +2 -0
- package/dist/src/error/__tests__/fatal.spec.d.ts.map +1 -0
- package/dist/src/error/__tests__/fatal.spec.js +34 -0
- package/dist/src/error/__tests__/fatal.spec.js.map +1 -0
- package/dist/src/error/action.d.ts +9 -0
- package/dist/src/error/action.d.ts.map +1 -0
- package/dist/src/error/action.js +16 -0
- package/dist/src/error/action.js.map +1 -0
- package/dist/src/error/base.d.ts +11 -0
- package/dist/src/error/base.d.ts.map +1 -0
- package/dist/src/error/base.js +18 -0
- package/dist/src/error/base.js.map +1 -0
- package/dist/src/error/fatal.d.ts +10 -0
- package/dist/src/error/fatal.d.ts.map +1 -0
- package/dist/src/error/fatal.js +27 -0
- package/dist/src/error/fatal.js.map +1 -0
- package/dist/src/error/index.d.ts +18 -0
- package/dist/src/error/index.d.ts.map +1 -0
- package/dist/src/error/index.js +34 -0
- package/dist/src/error/index.js.map +1 -0
- package/dist/src/error/invalid-validator.d.ts +10 -0
- package/dist/src/error/invalid-validator.d.ts.map +1 -0
- package/dist/src/error/invalid-validator.js +15 -0
- package/dist/src/error/invalid-validator.js.map +1 -0
- package/dist/src/error/missing-argument.d.ts +11 -0
- package/dist/src/error/missing-argument.d.ts.map +1 -0
- package/dist/src/error/missing-argument.js +20 -0
- package/dist/src/error/missing-argument.js.map +1 -0
- package/dist/src/error/missing-flag.d.ts +11 -0
- package/dist/src/error/missing-flag.d.ts.map +1 -0
- package/dist/src/error/missing-flag.js +20 -0
- package/dist/src/error/missing-flag.js.map +1 -0
- package/dist/src/error/multi-validation.d.ts +10 -0
- package/dist/src/error/multi-validation.d.ts.map +1 -0
- package/dist/src/error/multi-validation.js +26 -0
- package/dist/src/error/multi-validation.js.map +1 -0
- package/dist/src/error/no-action.d.ts +10 -0
- package/dist/src/error/no-action.d.ts.map +1 -0
- package/dist/src/error/no-action.js +22 -0
- package/dist/src/error/no-action.js.map +1 -0
- package/dist/src/error/option-synopsis-syntax.d.ts +9 -0
- package/dist/src/error/option-synopsis-syntax.d.ts.map +1 -0
- package/dist/src/error/option-synopsis-syntax.js +15 -0
- package/dist/src/error/option-synopsis-syntax.js.map +1 -0
- package/dist/src/error/too-many-arguments.d.ts +11 -0
- package/dist/src/error/too-many-arguments.d.ts.map +1 -0
- package/dist/src/error/too-many-arguments.js +25 -0
- package/dist/src/error/too-many-arguments.js.map +1 -0
- package/dist/src/error/unknown-command.d.ts +13 -0
- package/dist/src/error/unknown-command.d.ts.map +1 -0
- package/dist/src/error/unknown-command.js +44 -0
- package/dist/src/error/unknown-command.js.map +1 -0
- package/dist/src/error/unknown-option.d.ts +13 -0
- package/dist/src/error/unknown-option.d.ts.map +1 -0
- package/dist/src/error/unknown-option.js +40 -0
- package/dist/src/error/unknown-option.js.map +1 -0
- package/dist/src/error/validation.d.ts +17 -0
- package/dist/src/error/validation.d.ts.map +1 -0
- package/dist/src/error/validation.js +49 -0
- package/dist/src/error/validation.js.map +1 -0
- package/dist/src/help/__tests__/help.spec.d.ts +2 -0
- package/dist/src/help/__tests__/help.spec.d.ts.map +1 -0
- package/dist/src/help/__tests__/help.spec.js +130 -0
- package/dist/src/help/__tests__/help.spec.js.map +1 -0
- package/dist/src/help/__tests__/utils.spec.d.ts +2 -0
- package/dist/src/help/__tests__/utils.spec.d.ts.map +1 -0
- package/dist/src/help/__tests__/utils.spec.js +16 -0
- package/dist/src/help/__tests__/utils.spec.js.map +1 -0
- package/dist/src/help/index.d.ts +47 -0
- package/dist/src/help/index.d.ts.map +1 -0
- package/dist/src/help/index.js +131 -0
- package/dist/src/help/index.js.map +1 -0
- package/dist/src/help/templates/command.d.ts +7 -0
- package/dist/src/help/templates/command.d.ts.map +1 -0
- package/dist/src/help/templates/command.js +23 -0
- package/dist/src/help/templates/command.js.map +1 -0
- package/dist/src/help/templates/custom.d.ts +7 -0
- package/dist/src/help/templates/custom.d.ts.map +1 -0
- package/dist/src/help/templates/custom.js +24 -0
- package/dist/src/help/templates/custom.js.map +1 -0
- package/dist/src/help/templates/header.d.ts +7 -0
- package/dist/src/help/templates/header.d.ts.map +1 -0
- package/dist/src/help/templates/header.js +16 -0
- package/dist/src/help/templates/header.js.map +1 -0
- package/dist/src/help/templates/index.d.ts +10 -0
- package/dist/src/help/templates/index.d.ts.map +1 -0
- package/dist/src/help/templates/index.js +26 -0
- package/dist/src/help/templates/index.js.map +1 -0
- package/dist/src/help/templates/program.d.ts +7 -0
- package/dist/src/help/templates/program.d.ts.map +1 -0
- package/dist/src/help/templates/program.js +18 -0
- package/dist/src/help/templates/program.js.map +1 -0
- package/dist/src/help/templates/usage.d.ts +7 -0
- package/dist/src/help/templates/usage.d.ts.map +1 -0
- package/dist/src/help/templates/usage.js +19 -0
- package/dist/src/help/templates/usage.js.map +1 -0
- package/dist/src/help/types.d.ts +53 -0
- package/dist/src/help/types.d.ts.map +1 -0
- package/dist/src/help/types.js +3 -0
- package/dist/src/help/types.js.map +1 -0
- package/dist/src/help/utils.d.ts +9 -0
- package/dist/src/help/utils.d.ts.map +1 -0
- package/dist/src/help/utils.js +92 -0
- package/dist/src/help/utils.js.map +1 -0
- package/dist/src/index.d.ts +90 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +111 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/logger/__tests__/logger.spec.d.ts +2 -0
- package/dist/src/logger/__tests__/logger.spec.d.ts.map +1 -0
- package/dist/src/logger/__tests__/logger.spec.js +56 -0
- package/dist/src/logger/__tests__/logger.spec.js.map +1 -0
- package/dist/src/logger/index.d.ts +6 -0
- package/dist/src/logger/index.d.ts.map +1 -0
- package/dist/src/logger/index.js +128 -0
- package/dist/src/logger/index.js.map +1 -0
- package/dist/src/option/__tests__/global.spec.d.ts +2 -0
- package/dist/src/option/__tests__/global.spec.d.ts.map +1 -0
- package/dist/src/option/__tests__/global.spec.js +121 -0
- package/dist/src/option/__tests__/global.spec.js.map +1 -0
- package/dist/src/option/__tests__/option.spec.d.ts +2 -0
- package/dist/src/option/__tests__/option.spec.d.ts.map +1 -0
- package/dist/src/option/__tests__/option.spec.js +111 -0
- package/dist/src/option/__tests__/option.spec.js.map +1 -0
- package/dist/src/option/find.d.ts +14 -0
- package/dist/src/option/find.d.ts.map +1 -0
- package/dist/src/option/find.js +17 -0
- package/dist/src/option/find.js.map +1 -0
- package/dist/src/option/index.d.ts +65 -0
- package/dist/src/option/index.d.ts.map +1 -0
- package/dist/src/option/index.js +230 -0
- package/dist/src/option/index.js.map +1 -0
- package/dist/src/option/mapping.d.ts +7 -0
- package/dist/src/option/mapping.d.ts.map +1 -0
- package/dist/src/option/mapping.js +21 -0
- package/dist/src/option/mapping.js.map +1 -0
- package/dist/src/option/utils.d.ts +35 -0
- package/dist/src/option/utils.d.ts.map +1 -0
- package/dist/src/option/utils.js +139 -0
- package/dist/src/option/utils.js.map +1 -0
- package/dist/src/option/validate.d.ts +15 -0
- package/dist/src/option/validate.d.ts.map +1 -0
- package/dist/src/option/validate.js +63 -0
- package/dist/src/option/validate.js.map +1 -0
- package/dist/src/parser/__tests__/parser.spec.d.ts +2 -0
- package/dist/src/parser/__tests__/parser.spec.d.ts.map +1 -0
- package/dist/src/parser/__tests__/parser.spec.js +343 -0
- package/dist/src/parser/__tests__/parser.spec.js.map +1 -0
- package/dist/src/parser/index.d.ts +17 -0
- package/dist/src/parser/index.d.ts.map +1 -0
- package/dist/src/parser/index.js +299 -0
- package/dist/src/parser/index.js.map +1 -0
- package/dist/src/program/__tests__/program.spec.d.ts +2 -0
- package/dist/src/program/__tests__/program.spec.d.ts.map +1 -0
- package/dist/src/program/__tests__/program.spec.js +261 -0
- package/dist/src/program/__tests__/program.spec.js.map +1 -0
- package/dist/src/program/index.d.ts +349 -0
- package/dist/src/program/index.d.ts.map +1 -0
- package/dist/src/program/index.js +584 -0
- package/dist/src/program/index.js.map +1 -0
- package/dist/src/types.d.ts +396 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +51 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/utils/__tests__/fs.spec.d.ts +2 -0
- package/dist/src/utils/__tests__/fs.spec.d.ts.map +1 -0
- package/dist/src/utils/__tests__/fs.spec.js +14 -0
- package/dist/src/utils/__tests__/fs.spec.js.map +1 -0
- package/dist/src/utils/__tests__/levenshtein.spec.d.ts +2 -0
- package/dist/src/utils/__tests__/levenshtein.spec.d.ts.map +1 -0
- package/dist/src/utils/__tests__/levenshtein.spec.js +18 -0
- package/dist/src/utils/__tests__/levenshtein.spec.js.map +1 -0
- package/dist/src/utils/__tests__/suggest.spec.d.ts +2 -0
- package/dist/src/utils/__tests__/suggest.spec.d.ts.map +1 -0
- package/dist/src/utils/__tests__/suggest.spec.js +31 -0
- package/dist/src/utils/__tests__/suggest.spec.js.map +1 -0
- package/dist/src/utils/colorize.d.ts +2 -0
- package/dist/src/utils/colorize.d.ts.map +1 -0
- package/dist/src/utils/colorize.js +27 -0
- package/dist/src/utils/colorize.js.map +1 -0
- package/dist/src/utils/fs.d.ts +2 -0
- package/dist/src/utils/fs.d.ts.map +1 -0
- package/dist/src/utils/fs.js +19 -0
- package/dist/src/utils/fs.js.map +1 -0
- package/dist/src/utils/levenshtein.d.ts +6 -0
- package/dist/src/utils/levenshtein.d.ts.map +1 -0
- package/dist/src/utils/levenshtein.js +32 -0
- package/dist/src/utils/levenshtein.js.map +1 -0
- package/dist/src/utils/suggest.d.ts +15 -0
- package/dist/src/utils/suggest.d.ts.map +1 -0
- package/dist/src/utils/suggest.js +49 -0
- package/dist/src/utils/suggest.js.map +1 -0
- package/dist/src/utils/version.d.ts +2 -0
- package/dist/src/utils/version.d.ts.map +1 -0
- package/dist/src/utils/version.js +21 -0
- package/dist/src/utils/version.js.map +1 -0
- package/dist/src/utils/web/autocomplete.d.ts +12 -0
- package/dist/src/utils/web/autocomplete.d.ts.map +1 -0
- package/dist/src/utils/web/autocomplete.js +12 -0
- package/dist/src/utils/web/autocomplete.js.map +1 -0
- package/dist/src/utils/web/process.d.ts +15 -0
- package/dist/src/utils/web/process.d.ts.map +1 -0
- package/dist/src/utils/web/process.js +29 -0
- package/dist/src/utils/web/process.js.map +1 -0
- package/dist/src/validator/__tests__/array.spec.d.ts +2 -0
- package/dist/src/validator/__tests__/array.spec.d.ts.map +1 -0
- package/dist/src/validator/__tests__/array.spec.js +34 -0
- package/dist/src/validator/__tests__/array.spec.js.map +1 -0
- package/dist/src/validator/__tests__/caporal.spec.d.ts +2 -0
- package/dist/src/validator/__tests__/caporal.spec.d.ts.map +1 -0
- package/dist/src/validator/__tests__/caporal.spec.js +86 -0
- package/dist/src/validator/__tests__/caporal.spec.js.map +1 -0
- package/dist/src/validator/__tests__/function.spec.d.ts +2 -0
- package/dist/src/validator/__tests__/function.spec.d.ts.map +1 -0
- package/dist/src/validator/__tests__/function.spec.js +42 -0
- package/dist/src/validator/__tests__/function.spec.js.map +1 -0
- package/dist/src/validator/__tests__/regexp.spec.d.ts +2 -0
- package/dist/src/validator/__tests__/regexp.spec.d.ts.map +1 -0
- package/dist/src/validator/__tests__/regexp.spec.js +34 -0
- package/dist/src/validator/__tests__/regexp.spec.js.map +1 -0
- package/dist/src/validator/__tests__/utils.spec.d.ts +2 -0
- package/dist/src/validator/__tests__/utils.spec.d.ts.map +1 -0
- package/dist/src/validator/__tests__/utils.spec.js +66 -0
- package/dist/src/validator/__tests__/utils.spec.js.map +1 -0
- package/dist/src/validator/__tests__/validate.spec.d.ts +2 -0
- package/dist/src/validator/__tests__/validate.spec.d.ts.map +1 -0
- package/dist/src/validator/__tests__/validate.spec.js +25 -0
- package/dist/src/validator/__tests__/validate.spec.js.map +1 -0
- package/dist/src/validator/array.d.ts +14 -0
- package/dist/src/validator/array.d.ts.map +1 -0
- package/dist/src/validator/array.js +29 -0
- package/dist/src/validator/array.js.map +1 -0
- package/dist/src/validator/caporal.d.ts +25 -0
- package/dist/src/validator/caporal.d.ts.map +1 -0
- package/dist/src/validator/caporal.js +89 -0
- package/dist/src/validator/caporal.js.map +1 -0
- package/dist/src/validator/function.d.ts +7 -0
- package/dist/src/validator/function.d.ts.map +1 -0
- package/dist/src/validator/function.js +27 -0
- package/dist/src/validator/function.js.map +1 -0
- package/dist/src/validator/regexp.d.ts +14 -0
- package/dist/src/validator/regexp.d.ts.map +1 -0
- package/dist/src/validator/regexp.js +31 -0
- package/dist/src/validator/regexp.js.map +1 -0
- package/dist/src/validator/utils.d.ts +14 -0
- package/dist/src/validator/utils.d.ts.map +1 -0
- package/dist/src/validator/utils.js +81 -0
- package/dist/src/validator/utils.js.map +1 -0
- package/dist/src/validator/validate.d.ts +7 -0
- package/dist/src/validator/validate.d.ts.map +1 -0
- package/dist/src/validator/validate.js +29 -0
- package/dist/src/validator/validate.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +75 -0
- package/src/__tests__/issue-163.spec.ts +18 -0
- package/src/argument/__tests__/argument.spec.ts +84 -0
- package/src/argument/find.ts +11 -0
- package/src/argument/index.ts +35 -0
- package/src/argument/synopsis.ts +41 -0
- package/src/argument/validate.ts +176 -0
- package/src/autocomplete/__fixtures__/prog-autocomplete.ts +24 -0
- package/src/autocomplete/__tests__/autocomplete.spec.ts +129 -0
- package/src/autocomplete/index.ts +225 -0
- package/src/autocomplete/types.ts +29 -0
- package/src/command/__fixtures__/example-cmd.ts +14 -0
- package/src/command/__tests__/command.spec.ts +621 -0
- package/src/command/__tests__/find.spec.ts +32 -0
- package/src/command/__tests__/import.spec.ts +14 -0
- package/src/command/__tests__/scan.spec.ts +16 -0
- package/src/command/find.ts +57 -0
- package/src/command/import.ts +13 -0
- package/src/command/index.ts +458 -0
- package/src/command/scan.ts +30 -0
- package/src/command/validate-call.ts +19 -0
- package/src/config/index.ts +26 -0
- package/src/error/__tests__/fatal.spec.ts +38 -0
- package/src/error/action.ts +13 -0
- package/src/error/base.ts +20 -0
- package/src/error/fatal.ts +25 -0
- package/src/error/index.ts +17 -0
- package/src/error/invalid-validator.ts +12 -0
- package/src/error/missing-argument.ts +16 -0
- package/src/error/missing-flag.ts +16 -0
- package/src/error/multi-validation.ts +22 -0
- package/src/error/no-action.ts +19 -0
- package/src/error/option-synopsis-syntax.ts +12 -0
- package/src/error/too-many-arguments.ts +28 -0
- package/src/error/unknown-command.ts +41 -0
- package/src/error/unknown-option.ts +40 -0
- package/src/error/validation.ts +80 -0
- package/src/help/__tests__/__snapshots__/help.spec.ts.snap +334 -0
- package/src/help/__tests__/help.spec.ts +144 -0
- package/src/help/__tests__/utils.spec.ts +14 -0
- package/src/help/index.ts +107 -0
- package/src/help/templates/command.ts +27 -0
- package/src/help/templates/custom.ts +25 -0
- package/src/help/templates/header.ts +19 -0
- package/src/help/templates/index.ts +9 -0
- package/src/help/templates/program.ts +21 -0
- package/src/help/templates/usage.ts +24 -0
- package/src/help/types.ts +57 -0
- package/src/help/utils.ts +109 -0
- package/src/index.ts +93 -0
- package/src/logger/__tests__/logger.spec.ts +65 -0
- package/src/logger/index.ts +97 -0
- package/src/option/__tests__/global.spec.ts +141 -0
- package/src/option/__tests__/option.spec.ts +115 -0
- package/src/option/find.ts +17 -0
- package/src/option/index.ts +280 -0
- package/src/option/mapping.ts +17 -0
- package/src/option/utils.ts +141 -0
- package/src/option/validate.ts +80 -0
- package/src/parser/__tests__/parser.spec.ts +371 -0
- package/src/parser/index.ts +383 -0
- package/src/program/__tests__/program.spec.ts +316 -0
- package/src/program/index.ts +676 -0
- package/src/types.ts +432 -0
- package/src/utils/__tests__/fs.spec.ts +14 -0
- package/src/utils/__tests__/levenshtein.spec.ts +16 -0
- package/src/utils/__tests__/suggest.spec.ts +30 -0
- package/src/utils/colorize.ts +21 -0
- package/src/utils/fs.ts +13 -0
- package/src/utils/levenshtein.ts +28 -0
- package/src/utils/suggest.ts +52 -0
- package/src/utils/version.ts +14 -0
- package/src/utils/web/autocomplete.ts +19 -0
- package/src/utils/web/process.ts +24 -0
- package/src/validator/__tests__/array.spec.ts +41 -0
- package/src/validator/__tests__/caporal.spec.ts +132 -0
- package/src/validator/__tests__/function.spec.ts +52 -0
- package/src/validator/__tests__/regexp.spec.ts +38 -0
- package/src/validator/__tests__/utils.spec.ts +67 -0
- package/src/validator/__tests__/validate.spec.ts +24 -0
- package/src/validator/array.ts +31 -0
- package/src/validator/caporal.ts +104 -0
- package/src/validator/function.ts +31 -0
- package/src/validator/regexp.ts +34 -0
- package/src/validator/utils.ts +84 -0
- package/src/validator/validate.ts +38 -0
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @packageDocumentation
|
|
3
|
+
* @module parser
|
|
4
|
+
*/
|
|
5
|
+
import invert from "lodash/invert"
|
|
6
|
+
import findIndex from "lodash/findIndex"
|
|
7
|
+
import type {
|
|
8
|
+
ParserOptions,
|
|
9
|
+
ParserResult,
|
|
10
|
+
ParserTypes,
|
|
11
|
+
ParsedOptions,
|
|
12
|
+
ParsedArguments,
|
|
13
|
+
} from "../types"
|
|
14
|
+
import {
|
|
15
|
+
isNumeric,
|
|
16
|
+
isConcatenatedOpt,
|
|
17
|
+
isNegativeOpt,
|
|
18
|
+
isOptionStr,
|
|
19
|
+
formatOptName,
|
|
20
|
+
isOptArray,
|
|
21
|
+
} from "../option/utils"
|
|
22
|
+
|
|
23
|
+
const DDASH = "--"
|
|
24
|
+
|
|
25
|
+
function isDdash(str?: string): str is string {
|
|
26
|
+
return str === DDASH
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function castAsBool(value: string | boolean): boolean {
|
|
30
|
+
if (typeof value === "boolean") {
|
|
31
|
+
return value
|
|
32
|
+
}
|
|
33
|
+
return /^true|1|yes|on$/.test(value)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function castAsString(val: string | boolean): string {
|
|
37
|
+
return val + ""
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function autoCast(val: string): ParserTypes {
|
|
41
|
+
// auto-casting "true" & "false"
|
|
42
|
+
if (/^true|false$/.test(val)) {
|
|
43
|
+
return val === "true"
|
|
44
|
+
}
|
|
45
|
+
// auto-casting numbers
|
|
46
|
+
return isNumeric(val) ? parseFloat(val) : val
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function cast(name: string, val: string | true, options: ParserOptions): ParserTypes {
|
|
50
|
+
const cleanName = formatOptName(name)
|
|
51
|
+
|
|
52
|
+
// Force casting to string
|
|
53
|
+
if (options.string.includes(cleanName)) {
|
|
54
|
+
return castAsString(val)
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Force casting to bool
|
|
58
|
+
if (options.boolean.includes(cleanName) || typeof val === "boolean") {
|
|
59
|
+
return castAsBool(val)
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return options.autoCast ? autoCast(val) : val
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Parse a line
|
|
67
|
+
*
|
|
68
|
+
* @param line Line to be parsed
|
|
69
|
+
* @param options Parser options
|
|
70
|
+
* @internal
|
|
71
|
+
*/
|
|
72
|
+
export function parseLine(
|
|
73
|
+
line: string,
|
|
74
|
+
options: Partial<ParserOptions> = {},
|
|
75
|
+
): ParserResult {
|
|
76
|
+
return parseArgv(options, line.split(" "))
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
*
|
|
80
|
+
* @param args Return the next option position unless there is some ddash before
|
|
81
|
+
*/
|
|
82
|
+
function getNextOptPosition(args: string[]): number {
|
|
83
|
+
const ddash = args.indexOf("--")
|
|
84
|
+
const opt = findIndex(args, isOptionStr)
|
|
85
|
+
return ddash < opt && ddash !== -1 ? -1 : opt
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
class Tree {
|
|
89
|
+
cursor: number
|
|
90
|
+
private ddashHandled = false
|
|
91
|
+
|
|
92
|
+
constructor(private argv: string[]) {
|
|
93
|
+
this.cursor = 0
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/* istanbul ignore next */
|
|
97
|
+
toJSON(): {
|
|
98
|
+
cursor: number
|
|
99
|
+
ddashHandled: boolean
|
|
100
|
+
argv: string[]
|
|
101
|
+
current?: string
|
|
102
|
+
} {
|
|
103
|
+
return {
|
|
104
|
+
cursor: this.cursor,
|
|
105
|
+
ddashHandled: this.ddashHandled,
|
|
106
|
+
current: this.current,
|
|
107
|
+
argv: this.argv,
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
markDdashHandled(): Tree {
|
|
112
|
+
this.ddashHandled = true
|
|
113
|
+
return this
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
hasDdashHandled(): boolean {
|
|
117
|
+
return this.ddashHandled
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
next(): string | undefined {
|
|
121
|
+
return this.argv[this.cursor + 1]
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
slice(start?: number, end?: number): string[] {
|
|
125
|
+
return this.argv.slice(start, end)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
sliceFromHere(end?: number): string[] {
|
|
129
|
+
return this.slice(this.cursor, end)
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
forward(by = 1): true {
|
|
133
|
+
if (by === -1) {
|
|
134
|
+
return this.end()
|
|
135
|
+
}
|
|
136
|
+
this.cursor += by
|
|
137
|
+
return true
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
end(): true {
|
|
141
|
+
this.cursor = this.length
|
|
142
|
+
return true
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
get current(): string | undefined {
|
|
146
|
+
return this.argv[this.cursor]
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
get length(): number {
|
|
150
|
+
return this.argv.length
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
class ArgumentParser {
|
|
155
|
+
public readonly args: ParsedArguments = []
|
|
156
|
+
public readonly ddash: ParsedArguments = []
|
|
157
|
+
public readonly rawArgv: string[]
|
|
158
|
+
public readonly line: string
|
|
159
|
+
private variadicId?: number
|
|
160
|
+
private key: "args" | "ddash" = "args"
|
|
161
|
+
|
|
162
|
+
constructor(
|
|
163
|
+
private config: ParserOptions,
|
|
164
|
+
argv: string[],
|
|
165
|
+
) {
|
|
166
|
+
this.line = argv.join(" ")
|
|
167
|
+
this.rawArgv = argv
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
toJSON(): {
|
|
171
|
+
args: ParsedArguments
|
|
172
|
+
ddash: ParsedArguments
|
|
173
|
+
rawArgv: string[]
|
|
174
|
+
line: string
|
|
175
|
+
} {
|
|
176
|
+
return {
|
|
177
|
+
args: this.args,
|
|
178
|
+
ddash: this.ddash,
|
|
179
|
+
rawArgv: this.rawArgv,
|
|
180
|
+
line: this.line,
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
inVariadicContext(): boolean | undefined {
|
|
185
|
+
const argsLen = this[this.key].length
|
|
186
|
+
if (this.config.variadic.includes(argsLen)) {
|
|
187
|
+
this.variadicId = argsLen
|
|
188
|
+
}
|
|
189
|
+
if (this.variadicId !== undefined) {
|
|
190
|
+
return true
|
|
191
|
+
}
|
|
192
|
+
return undefined
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
markDdashHandled(tree: Tree): true {
|
|
196
|
+
if (this.config.ddash) {
|
|
197
|
+
// if ddash enabled, update the key
|
|
198
|
+
this.key = "ddash"
|
|
199
|
+
}
|
|
200
|
+
return tree.markDdashHandled().forward()
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
push(...values: string[]): true {
|
|
204
|
+
this[this.key].push(...values.map(this.config.autoCast ? autoCast : String))
|
|
205
|
+
return true
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
pushVariadic(tree: Tree): true {
|
|
209
|
+
const args = tree.sliceFromHere()
|
|
210
|
+
const until = getNextOptPosition(args)
|
|
211
|
+
this.variadicId = this.variadicId || 0
|
|
212
|
+
const variadic = (this[this.key][this.variadicId] =
|
|
213
|
+
(this[this.key][this.variadicId] as ParserTypes[]) || [])
|
|
214
|
+
|
|
215
|
+
variadic.push(
|
|
216
|
+
...args
|
|
217
|
+
.slice(0, until === -1 ? undefined : until)
|
|
218
|
+
.filter((s: string) => !isDdash(s))
|
|
219
|
+
.map(this.config.autoCast ? autoCast : String),
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
return tree.forward(until)
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
visit(tree: Tree): unknown {
|
|
226
|
+
if (!tree.current || (isOptionStr(tree.current) && !tree.hasDdashHandled())) {
|
|
227
|
+
return false
|
|
228
|
+
}
|
|
229
|
+
if (isDdash(tree.current)) {
|
|
230
|
+
return this.markDdashHandled(tree)
|
|
231
|
+
} else if (!this.inVariadicContext()) {
|
|
232
|
+
this.push(tree.current)
|
|
233
|
+
return tree.forward()
|
|
234
|
+
}
|
|
235
|
+
return this.pushVariadic(tree)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
class OptionParser {
|
|
240
|
+
public readonly options: ParsedOptions = {}
|
|
241
|
+
public readonly rawOptions: ParsedOptions = {}
|
|
242
|
+
|
|
243
|
+
constructor(private config: ParserOptions) {}
|
|
244
|
+
|
|
245
|
+
toJSON(): {
|
|
246
|
+
options: ParsedOptions
|
|
247
|
+
rawOptions: ParsedOptions
|
|
248
|
+
} {
|
|
249
|
+
return {
|
|
250
|
+
options: this.options,
|
|
251
|
+
rawOptions: this.rawOptions,
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
handleOptWithoutValue(name: string, tree: Tree): void {
|
|
256
|
+
const next = tree.next()
|
|
257
|
+
const nextIsOptOrUndef = isOptionStr(next) || isDdash(next) || next === undefined
|
|
258
|
+
this.compute(
|
|
259
|
+
name,
|
|
260
|
+
cast(name, nextIsOptOrUndef ? true : (next as string), this.config),
|
|
261
|
+
)
|
|
262
|
+
if (!nextIsOptOrUndef) {
|
|
263
|
+
tree.forward()
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
handleConcatenatedOpts(tree: Tree, names: string[], val?: ParserTypes): void {
|
|
268
|
+
if (val === undefined) {
|
|
269
|
+
val = true
|
|
270
|
+
const next = tree.next()
|
|
271
|
+
const last = names[names.length - 1]
|
|
272
|
+
const alias = this.config.alias[last]
|
|
273
|
+
const shouldTakeNextAsVal =
|
|
274
|
+
next && !isOptionStr(next) && !isDdash(next) && !this.isBoolean(last, alias)
|
|
275
|
+
if (shouldTakeNextAsVal) {
|
|
276
|
+
tree.forward()
|
|
277
|
+
val = next as string
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
this.computeMulti(names, val)
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
visit(tree: Tree): boolean {
|
|
284
|
+
// only handle options
|
|
285
|
+
/* istanbul ignore if */
|
|
286
|
+
if (!tree.current || !isOptionStr(tree.current) || tree.hasDdashHandled()) {
|
|
287
|
+
// this is never reached because the scan stops if
|
|
288
|
+
// a visior returns true, and as the Argument visitor is the first in the
|
|
289
|
+
// list, arguments objects never reach the Options visitor
|
|
290
|
+
// keeping it here in case we change the order of visitors
|
|
291
|
+
return false
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const [name, rawval] = tree.current.split("=", 2)
|
|
295
|
+
const concatOpts = isConcatenatedOpt(name)
|
|
296
|
+
|
|
297
|
+
if (concatOpts) {
|
|
298
|
+
this.handleConcatenatedOpts(tree, concatOpts, rawval)
|
|
299
|
+
} else if (rawval) {
|
|
300
|
+
this.compute(name, cast(name, rawval, this.config))
|
|
301
|
+
} else {
|
|
302
|
+
this.handleOptWithoutValue(name, tree)
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
return tree.forward()
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
compute(name: string, val: ParserTypes): void {
|
|
309
|
+
const no = isNegativeOpt(name)
|
|
310
|
+
const cleanName = formatOptName(name)
|
|
311
|
+
const alias = this.config.alias[cleanName]
|
|
312
|
+
|
|
313
|
+
if (this.isVariadic(cleanName, alias)) {
|
|
314
|
+
const prop = this.options[cleanName]
|
|
315
|
+
this.rawOptions[name] = this.options[cleanName] = (
|
|
316
|
+
isOptArray(prop) ? prop : [prop]
|
|
317
|
+
).concat(val)
|
|
318
|
+
} else {
|
|
319
|
+
this.rawOptions[name] = this.options[cleanName] = no ? !val : val
|
|
320
|
+
}
|
|
321
|
+
if (alias) {
|
|
322
|
+
this.options[alias] = this.options[cleanName]
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// todo: handle variadic, even for compute multi
|
|
327
|
+
// TIP: (maybe just split and redirect the last char to compute())
|
|
328
|
+
computeMulti(multi: string[], val: ParserTypes): void {
|
|
329
|
+
const n = multi.length
|
|
330
|
+
multi.forEach((o, index) => {
|
|
331
|
+
const alias = this.config.alias[o]
|
|
332
|
+
this.options[o] = index + 1 === n ? cast(o, val as string, this.config) : true
|
|
333
|
+
this.rawOptions["-" + o] = this.options[o]
|
|
334
|
+
if (alias) {
|
|
335
|
+
this.options[alias] = this.options[o]
|
|
336
|
+
}
|
|
337
|
+
})
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
isVariadic(name: string, alias: string): boolean {
|
|
341
|
+
return (
|
|
342
|
+
name in this.options &&
|
|
343
|
+
(this.config.variadic.includes(name) || this.config.variadic.includes(alias))
|
|
344
|
+
)
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
isBoolean(name: string, alias: string): boolean {
|
|
348
|
+
return this.config.boolean.includes(name) || this.config.boolean.includes(alias)
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Parse command line arguments
|
|
354
|
+
*
|
|
355
|
+
* @param options Parser options
|
|
356
|
+
* @param argv command line arguments array (a.k.a. "argv")
|
|
357
|
+
*/
|
|
358
|
+
export function parseArgv(
|
|
359
|
+
options: Partial<ParserOptions> = {},
|
|
360
|
+
argv: string[] = process.argv.slice(2),
|
|
361
|
+
): ParserResult {
|
|
362
|
+
const parseOpts: ParserOptions = {
|
|
363
|
+
autoCast: true,
|
|
364
|
+
ddash: false,
|
|
365
|
+
alias: {},
|
|
366
|
+
boolean: [],
|
|
367
|
+
string: [],
|
|
368
|
+
variadic: [],
|
|
369
|
+
...options,
|
|
370
|
+
}
|
|
371
|
+
parseOpts.alias = { ...parseOpts.alias, ...invert(parseOpts.alias) }
|
|
372
|
+
|
|
373
|
+
const tree = new Tree(argv)
|
|
374
|
+
const flagParser = new OptionParser(parseOpts)
|
|
375
|
+
const argParser = new ArgumentParser(parseOpts, argv)
|
|
376
|
+
const visitors = [argParser, flagParser]
|
|
377
|
+
|
|
378
|
+
while (tree.current) {
|
|
379
|
+
visitors.some((v) => v.visit(tree))
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
return { ...flagParser.toJSON(), ...argParser.toJSON() }
|
|
383
|
+
}
|
|
@@ -0,0 +1,316 @@
|
|
|
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 { program } from "../../index"
|
|
16
|
+
import { Program } from ".."
|
|
17
|
+
import {
|
|
18
|
+
UnknownOrUnspecifiedCommandError,
|
|
19
|
+
ValidationSummaryError,
|
|
20
|
+
NoActionError,
|
|
21
|
+
} from "../../error"
|
|
22
|
+
import { Logger } from "../../types"
|
|
23
|
+
import { logger } from "../../logger"
|
|
24
|
+
import { resetGlobalOptions } from "../../option"
|
|
25
|
+
|
|
26
|
+
let prog = program
|
|
27
|
+
|
|
28
|
+
const loggerWarnSpy = vi.spyOn(logger, "warn")
|
|
29
|
+
|
|
30
|
+
describe("Program", () => {
|
|
31
|
+
beforeEach(() => {
|
|
32
|
+
prog = new Program()
|
|
33
|
+
prog.name("test-prog")
|
|
34
|
+
prog.bin("test-prog")
|
|
35
|
+
vi.clearAllMocks()
|
|
36
|
+
resetGlobalOptions()
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
it(".version() should set the version", () => {
|
|
40
|
+
prog.version("beta-2")
|
|
41
|
+
expect(prog.getVersion()).toBe("beta-2")
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
it(".description() should set the description", () => {
|
|
45
|
+
prog.description("fake-desc")
|
|
46
|
+
expect(prog.getDescription()).toBe("fake-desc")
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
it(".hasCommands() should return false by default", () => {
|
|
50
|
+
return expect(prog.hasCommands()).resolves.toBe(false)
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
it(".getSynopsis should return the correct synopsis if program has commands", () => {
|
|
54
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
55
|
+
prog.command("my-command", "my command").action(action)
|
|
56
|
+
return expect(prog.getSynopsis()).resolves.toContain("<command>")
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
it(".synospis should return the correct synopsis if program does not have commands", () => {
|
|
60
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
61
|
+
prog.action(action)
|
|
62
|
+
return expect(prog.getSynopsis()).resolves.not.toContain("<command>")
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
it(".parse(undefined) should work", async () => {
|
|
66
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
67
|
+
prog.argument("[first-arg]", "First argument").action(action)
|
|
68
|
+
await expect(prog.run([])).resolves.toBe("ok")
|
|
69
|
+
expect(action).toHaveBeenCalled()
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
it("should be able to create a 'program-command' just by calling .argument()", async () => {
|
|
73
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
74
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
75
|
+
await expect(prog.run(["first-arg"])).resolves.toBe("ok")
|
|
76
|
+
expect(action).toHaveBeenCalled()
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
it("should be able to create a 'program-command' just by calling .option()", async () => {
|
|
80
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
81
|
+
prog.option("--foo", "Foo option").action(action)
|
|
82
|
+
await expect(prog.run(["--foo"])).resolves.toBe("ok")
|
|
83
|
+
expect(action).toHaveBeenCalled()
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
it(".globalOption() should create a global option without associated action", async () => {
|
|
87
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
88
|
+
prog.option("--my-global <var>", "my global var", { global: true })
|
|
89
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
90
|
+
|
|
91
|
+
await expect(prog.run(["first-arg", "--my-global", "secret"])).resolves.toBe("ok")
|
|
92
|
+
expect(action).toHaveBeenCalled()
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
it(".globalOption() should create a global option with associated action", async () => {
|
|
96
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
97
|
+
const optAction = vi.fn()
|
|
98
|
+
prog.option("--my-global <var>", "my global var", { global: true, action: optAction })
|
|
99
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
100
|
+
|
|
101
|
+
await expect(prog.run(["first-arg", "--my-global", "secret"])).resolves.toBe("ok")
|
|
102
|
+
expect(action).toHaveBeenCalled()
|
|
103
|
+
expect(optAction).toHaveBeenCalled()
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
it("disableGlobalOption() should disable a global option", async () => {
|
|
107
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
108
|
+
const optAction = vi.fn()
|
|
109
|
+
prog.option("--my-global <var>", "my global var", { global: true, action: optAction })
|
|
110
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
111
|
+
prog.strict(false)
|
|
112
|
+
prog.disableGlobalOption("myGlobal")
|
|
113
|
+
|
|
114
|
+
// second call should call console.warn
|
|
115
|
+
prog.disableGlobalOption("myGlobal")
|
|
116
|
+
|
|
117
|
+
await expect(prog.run(["first-arg", "--my-global", "secret"])).resolves.toBe("ok")
|
|
118
|
+
expect(action).toHaveBeenCalled()
|
|
119
|
+
expect(optAction).not.toHaveBeenCalled()
|
|
120
|
+
expect(loggerWarnSpy).toHaveBeenCalled()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
it(".discover() should set discovery path if it exists", () => {
|
|
124
|
+
prog.discover(".")
|
|
125
|
+
expect(prog.discoveryPath).toBe(".")
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
it(".discover() should throw if provided path does not exist", () => {
|
|
129
|
+
return expect(() => prog.discover("/unknown/path")).toThrowError()
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
it(".discover() should throw if provided path is not a directory", () => {
|
|
133
|
+
return expect(() => prog.discover(__filename)).toThrowError()
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
it("should be able to call discovered commands", async () => {
|
|
137
|
+
prog.discover(__dirname + "/../../command/__fixtures__")
|
|
138
|
+
await expect(prog.run(["example-cmd"])).resolves.toBe("hey")
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
it("should be able to call .argument() multiple times", async () => {
|
|
142
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
143
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
144
|
+
prog.argument("<second-arg>", "Second argument").action(action)
|
|
145
|
+
await expect(prog.run(["first-arg", "sec-arg"])).resolves.toBe("ok")
|
|
146
|
+
expect(action).toHaveBeenCalled()
|
|
147
|
+
})
|
|
148
|
+
|
|
149
|
+
it(".run() should work without arguments", async () => {
|
|
150
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
151
|
+
prog.strict(false)
|
|
152
|
+
prog.action(action)
|
|
153
|
+
await expect(prog.run()).resolves.toBe("ok")
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it(".run() should throw an Error when no action is defined for the program-command", async () => {
|
|
157
|
+
prog.option("-t, --type <pizza-type>", "Pizza type")
|
|
158
|
+
await expect(prog.run([])).rejects.toBeInstanceOf(NoActionError)
|
|
159
|
+
})
|
|
160
|
+
|
|
161
|
+
it("should be able to create a 'program-command' just by calling .action()", async () => {
|
|
162
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
163
|
+
prog.action(action)
|
|
164
|
+
await expect(prog.run([])).resolves.toBe("ok")
|
|
165
|
+
expect(action).toHaveBeenCalled()
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
it(".exec() should work as expected", async () => {
|
|
169
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
170
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
171
|
+
await expect(prog.exec(["1"])).resolves.toBe("ok")
|
|
172
|
+
expect(action).toHaveBeenCalledWith(
|
|
173
|
+
expect.objectContaining({
|
|
174
|
+
args: {
|
|
175
|
+
firstArg: "1",
|
|
176
|
+
},
|
|
177
|
+
}),
|
|
178
|
+
)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
it(".cast(true) should enable auto casting", async () => {
|
|
182
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
183
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
184
|
+
prog.cast(true)
|
|
185
|
+
await expect(prog.run(["1"])).resolves.toBe("ok")
|
|
186
|
+
expect(action).toHaveBeenCalledWith(
|
|
187
|
+
expect.objectContaining({
|
|
188
|
+
args: {
|
|
189
|
+
firstArg: 1,
|
|
190
|
+
},
|
|
191
|
+
}),
|
|
192
|
+
)
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
it(".cast(false) should disable auto casting", async () => {
|
|
196
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
197
|
+
prog.argument("<first-arg>", "First argument").action(action)
|
|
198
|
+
prog.cast(false)
|
|
199
|
+
await expect(prog.run(["1"])).resolves.toBe("ok")
|
|
200
|
+
expect(action).toHaveBeenCalledWith(
|
|
201
|
+
expect.objectContaining({
|
|
202
|
+
args: {
|
|
203
|
+
firstArg: "1",
|
|
204
|
+
},
|
|
205
|
+
}),
|
|
206
|
+
)
|
|
207
|
+
})
|
|
208
|
+
|
|
209
|
+
it("program should create help command and accept executing 'program help'", async () => {
|
|
210
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
211
|
+
prog
|
|
212
|
+
.command("test", "test command")
|
|
213
|
+
.argument("<first-arg>", "First argument")
|
|
214
|
+
.action(action)
|
|
215
|
+
await expect(prog.run(["help"])).resolves.toBe(-1)
|
|
216
|
+
await expect(prog.run(["help", "test"])).resolves.toBe(-1)
|
|
217
|
+
expect(action).not.toHaveBeenCalled()
|
|
218
|
+
expect(mocks.fatalError).not.toHaveBeenCalled()
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
it("program should create help command and accept executing 'program help command-name'", async () => {
|
|
222
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
223
|
+
prog
|
|
224
|
+
.command("test", "test command")
|
|
225
|
+
.argument("<first-arg>", "First argument")
|
|
226
|
+
.action(action)
|
|
227
|
+
await expect(prog.run(["help", "test"])).resolves.toBe(-1)
|
|
228
|
+
expect(action).not.toHaveBeenCalled()
|
|
229
|
+
expect(mocks.fatalError).not.toHaveBeenCalled()
|
|
230
|
+
})
|
|
231
|
+
|
|
232
|
+
it("program should create help command and accept executing 'program help unknown-command'", async () => {
|
|
233
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
234
|
+
prog
|
|
235
|
+
.command("test", "test command")
|
|
236
|
+
.argument("<first-arg>", "First argument")
|
|
237
|
+
.action(action)
|
|
238
|
+
await expect(prog.run(["help", "unknown"])).resolves.toBe(-1)
|
|
239
|
+
expect(action).not.toHaveBeenCalled()
|
|
240
|
+
expect(mocks.fatalError).not.toHaveBeenCalled()
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
it("'program help' should work for a program without any command", async () => {
|
|
244
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
245
|
+
prog.bin("test").argument("<first-arg>", "First argument").action(action)
|
|
246
|
+
await expect(prog.run(["help"])).resolves.toBe(-1)
|
|
247
|
+
expect(action).not.toHaveBeenCalled()
|
|
248
|
+
expect(mocks.fatalError).not.toHaveBeenCalled()
|
|
249
|
+
})
|
|
250
|
+
|
|
251
|
+
it("'program' should throw for a program without any command but a required arg", async () => {
|
|
252
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
253
|
+
prog.bin("test").argument("<first-arg>", "First argument").action(action)
|
|
254
|
+
await expect(prog.run([])).rejects.toBeInstanceOf(ValidationSummaryError)
|
|
255
|
+
expect(action).not.toHaveBeenCalled()
|
|
256
|
+
})
|
|
257
|
+
|
|
258
|
+
it("program should fail when trying to run an unknown command", async () => {
|
|
259
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
260
|
+
prog
|
|
261
|
+
.command("test", "test command")
|
|
262
|
+
.argument("<first-arg>", "First argument")
|
|
263
|
+
.action(action)
|
|
264
|
+
await expect(prog.run(["unknown-cmd"])).rejects.toBeInstanceOf(
|
|
265
|
+
UnknownOrUnspecifiedCommandError,
|
|
266
|
+
)
|
|
267
|
+
})
|
|
268
|
+
|
|
269
|
+
it("program should fail when trying to run an unknown command and suggest some commands", async () => {
|
|
270
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
271
|
+
prog
|
|
272
|
+
.command("test", "test command")
|
|
273
|
+
.argument("<first-arg>", "First argument")
|
|
274
|
+
.action(action)
|
|
275
|
+
await expect(prog.run(["rest"])).rejects.toBeInstanceOf(
|
|
276
|
+
UnknownOrUnspecifiedCommandError,
|
|
277
|
+
)
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
it("program should fail when trying to run without a specified command", async () => {
|
|
281
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
282
|
+
prog
|
|
283
|
+
.command("test", "test command")
|
|
284
|
+
.argument("<first-arg>", "First argument")
|
|
285
|
+
.action(action)
|
|
286
|
+
await expect(prog.run([])).rejects.toBeInstanceOf(UnknownOrUnspecifiedCommandError)
|
|
287
|
+
})
|
|
288
|
+
|
|
289
|
+
it(".setLogLevelEnvVar() should set the log level ENV var", async () => {
|
|
290
|
+
process.env.MY_ENV_VAR = "warn"
|
|
291
|
+
prog.configure({ logLevelEnvVar: "MY_ENV_VAR" })
|
|
292
|
+
const action = vi.fn().mockReturnValue("ok")
|
|
293
|
+
prog
|
|
294
|
+
.command("test", "test command")
|
|
295
|
+
.argument("<first-arg>", "First argument")
|
|
296
|
+
.action(action)
|
|
297
|
+
expect(prog.getLogLevelOverride()).toBe("warn")
|
|
298
|
+
await prog.run(["test", "my-arg"])
|
|
299
|
+
expect(logger.level).toBe("warn")
|
|
300
|
+
})
|
|
301
|
+
|
|
302
|
+
it(".logger() should override the default logger", async () => {
|
|
303
|
+
const action = vi.fn().mockImplementation(({ logger }) => {
|
|
304
|
+
logger.log("foo")
|
|
305
|
+
return true
|
|
306
|
+
})
|
|
307
|
+
const logger = { log: vi.fn() }
|
|
308
|
+
prog
|
|
309
|
+
.logger(logger as unknown as Logger)
|
|
310
|
+
.command("test", "test command")
|
|
311
|
+
.argument("<first-arg>", "First argument")
|
|
312
|
+
.action(action)
|
|
313
|
+
await expect(prog.run(["test", "my-arg"])).resolves.toBe(true)
|
|
314
|
+
expect(logger.log).toHaveBeenCalledWith("foo")
|
|
315
|
+
})
|
|
316
|
+
})
|