zod-args-parser 1.0.2 → 1.0.3
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 +14 -4
- package/lib/commonjs/index.js +1 -1
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/types.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/types.js.map +1 -1
- package/lib/typescript/index.d.ts +5 -4
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/types.d.ts +30 -2
- package/lib/typescript/types.d.ts.map +1 -1
- package/package.json +16 -2
- package/src/index.ts +16 -4
- package/src/types.ts +56 -7
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Ahmed Alabsi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -6,6 +6,7 @@ A strictly typed command-line arguments parser powered by Zod.
|
|
|
6
6
|
|
|
7
7
|
- **Strict typing for subcommands, options, and arguments**.
|
|
8
8
|
- **Flag coupling support**: e.g., `-rf` to combine `-r` and `-f` flags.
|
|
9
|
+
- **Negative flag support**: e.g., `--no-verbose` to negate `--verbose`.
|
|
9
10
|
- **Flexible option value formatting**: Supports both `--input-dir path` and `--input-dir=path` styles.
|
|
10
11
|
- **Help message generation**: Built-in methods to generate help text for the CLI and each subcommand.
|
|
11
12
|
|
|
@@ -18,7 +19,17 @@ npm install zod-args-parser
|
|
|
18
19
|
## Usage
|
|
19
20
|
|
|
20
21
|
```ts
|
|
21
|
-
import { createCli, createSubcommand, safeParse } from "zod-args-parser";
|
|
22
|
+
import { createCli, createSubcommand, createOptions, safeParse } from "zod-args-parser";
|
|
23
|
+
|
|
24
|
+
// Share same options between subcommands
|
|
25
|
+
const sharedOptions = createOptions([
|
|
26
|
+
{
|
|
27
|
+
name: "verbose",
|
|
28
|
+
aliases: ["v"],
|
|
29
|
+
description: "Verbose mode",
|
|
30
|
+
type: z.boolean().optional(),
|
|
31
|
+
},
|
|
32
|
+
]);
|
|
22
33
|
|
|
23
34
|
// Create a CLI schema
|
|
24
35
|
// This will be used when no subcommands are provided
|
|
@@ -33,6 +44,7 @@ const cliProgram = createCli({
|
|
|
33
44
|
aliases: ["h"],
|
|
34
45
|
type: z.boolean(),
|
|
35
46
|
},
|
|
47
|
+
...sharedOptions,
|
|
36
48
|
],
|
|
37
49
|
});
|
|
38
50
|
|
|
@@ -108,9 +120,7 @@ type Arguments = InferArgumentsType<typeof subcommand>;
|
|
|
108
120
|
|
|
109
121
|
## API
|
|
110
122
|
|
|
111
|
-
### `
|
|
112
|
-
|
|
113
|
-
Defines a subcommand with associated options and arguments.
|
|
123
|
+
### `Subcommand`
|
|
114
124
|
|
|
115
125
|
- `name: string`
|
|
116
126
|
The name of the subcommand.
|
package/lib/commonjs/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.createCli=createCli;exports.createSubcommand=createSubcommand;Object.defineProperty(exports,"parse",{enumerable:true,get:function(){return _parser.parse;}});exports.printSubcommandHelp=exports.printCliHelp=void 0;Object.defineProperty(exports,"safeParse",{enumerable:true,get:function(){return _parser.safeParse;}});var _help=require("./help.js");var _parser=require("./parser.js");function createSubcommand(input){return Object.assign(input,{setAction:action=>input.action=action});}function createCli(input){return Object.assign(input,{setAction:action=>input.action=action});}const{printCliHelp,printSubcommandHelp}=_help.help;exports.printSubcommandHelp=printSubcommandHelp;exports.printCliHelp=printCliHelp;
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.createCli=createCli;exports.createOptions=createOptions;exports.createSubcommand=createSubcommand;Object.defineProperty(exports,"parse",{enumerable:true,get:function(){return _parser.parse;}});exports.printSubcommandHelp=exports.printCliHelp=void 0;Object.defineProperty(exports,"safeParse",{enumerable:true,get:function(){return _parser.safeParse;}});var _help=require("./help.js");var _parser=require("./parser.js");function createSubcommand(input){return Object.assign(input,{setAction:action=>input.action=action});}function createCli(input){return Object.assign(input,{setAction:action=>input.action=action});}function createOptions(options){return options;}const{printCliHelp,printSubcommandHelp}=_help.help;exports.printSubcommandHelp=printSubcommandHelp;exports.printCliHelp=printCliHelp;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_help","require","_parser","createSubcommand","input","Object","assign","setAction","action","createCli","printCliHelp","printSubcommandHelp","help","exports"],"sourceRoot":"../../src","sources":["index.ts"],"sourcesContent":["import { help } from \"./help.js\";\nimport { parse, safeParse } from \"./parser.js\";\n\nimport type {
|
|
1
|
+
{"version":3,"names":["_help","require","_parser","createSubcommand","input","Object","assign","setAction","action","createCli","createOptions","options","printCliHelp","printSubcommandHelp","help","exports"],"sourceRoot":"../../src","sources":["index.ts"],"sourcesContent":["import { help } from \"./help.js\";\nimport { parse, safeParse } from \"./parser.js\";\n\nimport type {\n ActionFn,\n CheckDuplicatedOptions,\n Cli,\n Option,\n Prettify,\n Subcommand,\n UnSafeParseResult,\n} from \"./types.js\";\n\nfunction createSubcommand<const T extends Subcommand>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>> {\n return Object.assign(input, {\n setAction: (action: (res: UnSafeParseResult<[T]>) => void) => (input.action = action),\n });\n}\n\nfunction createCli<const T extends Cli>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>> {\n return Object.assign(input, {\n setAction: (action: (res: UnSafeParseResult<[T]>) => void) => (input.action = action),\n });\n}\n\nfunction createOptions<const T extends [Option, ...Option[]]>(options: T): T {\n return options;\n}\n\nconst { printCliHelp, printSubcommandHelp } = help;\n\nexport { createCli, createSubcommand, createOptions, parse, printCliHelp, printSubcommandHelp, safeParse };\n\nexport type * from \"./types.js\";\n"],"mappings":"8aAAA,IAAAA,KAAA,CAAAC,OAAA,cACA,IAAAC,OAAA,CAAAD,OAAA,gBAYA,QAAS,CAAAE,gBAAgBA,CAA6BC,KAAgC,CAA6B,CACjH,MAAO,CAAAC,MAAM,CAACC,MAAM,CAACF,KAAK,CAAE,CAC1BG,SAAS,CAAGC,MAA6C,EAAMJ,KAAK,CAACI,MAAM,CAAGA,MAChF,CAAC,CAAC,CACJ,CAEA,QAAS,CAAAC,SAASA,CAAsBL,KAAgC,CAA6B,CACnG,MAAO,CAAAC,MAAM,CAACC,MAAM,CAACF,KAAK,CAAE,CAC1BG,SAAS,CAAGC,MAA6C,EAAMJ,KAAK,CAACI,MAAM,CAAGA,MAChF,CAAC,CAAC,CACJ,CAEA,QAAS,CAAAE,aAAaA,CAAwCC,OAAU,CAAK,CAC3E,MAAO,CAAAA,OAAO,CAChB,CAEA,KAAM,CAAEC,YAAY,CAAEC,mBAAoB,CAAC,CAAGC,UAAI,CAACC,OAAA,CAAAF,mBAAA,CAAAA,mBAAA,CAAAE,OAAA,CAAAH,YAAA,CAAAA,YAAA","ignoreList":[]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"sourcesContent":["import type { z } from \"zod\";\n\nexport type Subcommand = {\n /**\n * - The subcommand name, use `kebab-case`.\n * - Make sure to not duplicate commands and aliases.\n *\n * @example\n * name: \"test\";\n * name: \"run-app\";\n */\n name: string;\n\n /**\n * - The action is executed with the result of the parsed arguments.\n * - To get typescript types use `setAction` instead of this.\n *\n * @example\n * const helpCommand = createSubcommand({ name: \"help\", options: [...] });\n * helpCommand.setAction(res => console.log(res));\n */\n action?: (results?: any) => void;\n\n /**\n * - The description of the subcommand.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - Provide an example to show to the user.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the subcommand.\n * - Make sure to not duplicate aliases and commands.\n */\n aliases?: string[];\n\n /**\n * - Allows positional arguments for this subcommand.\n * - Unlike `arguments`, which are strictly typed, positional arguments are untyped and represented as a string array of\n * variable length.\n * - When enabled and `arguments` are provided, `arguments` will be parsed first. Any remaining arguments will be\n * considered positional arguments and added to the `positional` property in the result.\n */\n allowPositional?: boolean;\n\n /**\n * - The options of the command.\n * - Those options are specific to this subcommand.\n */\n options?: [Option, ...Option[]];\n\n /**\n * - Specifies a list of strictly typed arguments.\n * - The order is important; for example, the first argument will be validated against the first specified type.\n * - It is recommended to not use optional arguments as the parser will fill the arguments by order and can't determine\n * which arguments are optional.\n */\n arguments?: [Argument, ...Argument[]];\n};\n\nexport type Cli = Prettify<\n Omit<Subcommand, \"name\"> & {\n /** - The name of the CLI program. */\n cliName: string;\n\n /**\n * - The usage of the CLI program.\n * - Used for generating the help message.\n */\n usage?: string;\n }\n>;\n\nexport type Option = {\n /**\n * - The name of the option, use `CamelCase`.\n * - For example: the syntax for the option `rootPath` is `--root-path`.\n */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean().default(false);\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(parseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the option.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - The example of using the option.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the option, use `CamelCase`.\n * - Here you can specify short names or flags.\n * - Make sure to not duplicate aliases.\n */\n aliases?: [string, ...string[]];\n};\n\nexport type Argument = {\n /** - The name of the argument. */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean();\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(ParseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the argument.\n * - Used for generating the help message.\n */\n description?: string;\n\n /**\n * - The example of using the argument.\n * - Used for generating the help message.\n */\n example?: string;\n};\n\nexport type ColorFnType = (...text: unknown[]) => string;\n\nexport type PrintHelpOpt = {\n /**\n * - **Optional** `boolean`\n * - Whether to print colors or not.\n * - Default: `true`\n */\n colors?: boolean;\n\n /**\n * - **Optional** `object`\n * - The colors to use for the help message.\n */\n customColors?: {\n title?: ColorFnType;\n description?: ColorFnType;\n default?: ColorFnType;\n optional?: ColorFnType;\n exampleTitle?: ColorFnType;\n example?: ColorFnType;\n command?: ColorFnType;\n option?: ColorFnType;\n argument?: ColorFnType;\n placeholder?: ColorFnType;\n punctuation?: ColorFnType;\n };\n};\n\nexport type _Info = {\n /**\n * - The raw argument as it was passed in\n * - For options that have a default value and are not passed in, the raw argument will be `undefined`\n */\n rawArg?: string;\n /**\n * - The raw value of the argument as it was passed in\n * - It will be empty string for `boolean` options. E.g. `--help` or `-h`\n * - For options that have a default value and are not passed in, the raw value will be `undefined`\n */\n rawValue?: string;\n /**\n * - The source value of the argument:\n * - `cli`: The argument was passed in by the user\n * - `default`: The argument was not passed in and has a default value\n */\n source: \"cli\" | \"default\";\n};\n\n/**\n * - Infer the options type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", options: [...] });\n * type OptionsType = InferOptionsType<typeof subcommand>;\n */\nexport type InferOptionsType<T extends Partial<Subcommand>> = T[\"options\"] extends infer U extends Option[]\n ? ToOptional<{ [K in U[number][\"name\"]]: z.infer<Extract<U[number], { name: K }>[\"type\"]> }>\n : undefined;\n\n/**\n * - Infer the arguments type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", arguments: [...] });\n * type ArgumentsType = InferArgumentsType<typeof subcommand>;\n */\nexport type InferArgumentsType<T extends Partial<Subcommand>> = T[\"arguments\"] extends infer U extends Argument[]\n ? { [K in keyof U]: U[K] extends { type: z.ZodTypeAny } ? z.infer<U[K][\"type\"]> : never }\n : undefined;\n\n/** `{ some props } & { other props }` => `{ some props, other props }` */\nexport type Prettify<T> = { [K in keyof T]: T[K] } & {};\n\n/** Allow string type for literal union and get auto completion */\nexport type LiteralUnion<T extends string> = T | (string & {});\n\n/** Extract the undefined properties from an object */\ntype UndefinedProperties<T> = { [P in keyof T]-?: undefined extends T[P] ? P : never }[keyof T];\n\n/** Make undefined properties optional? */\ntype ToOptional<T> = Prettify<\n Partial<Pick<T, UndefinedProperties<T>>> & Pick<T, Exclude<keyof T, UndefinedProperties<T>>>\n>;\n\nexport type OptionsArr2RecordType<T extends Option[] | undefined> = T extends Option[]\n ? ToOptional<{ [K in T[number][\"name\"]]: z.infer<Extract<T[number], { name: K }>[\"type\"]> }>\n : object;\n\nexport type ArgumentsArr2ArrType<T extends Argument[] | undefined> = T extends Argument[]\n ? { arguments: { [K in keyof T]: T[K] extends { type: z.ZodTypeAny } ? z.infer<T[K][\"type\"]> : never } }\n : object;\n\nexport type Positional<S extends Partial<Subcommand>> = S[\"allowPositional\"] extends true ? { positional: string[] } : object;\n\nexport type Info<T extends Option[] | undefined> = T extends Option[]\n ? {\n _info: ToOptional<{\n [K in T[number][\"name\"]]: Extract<T[number], { name: K }> extends infer U extends Option\n ? undefined extends z.infer<U[\"type\"]>\n ? undefined | Prettify<_Info & U> // if optional add undefined\n : Prettify<_Info & U>\n : never;\n }>;\n }\n : object;\n\nexport type NoSubcommand = { name: undefined };\n\nexport type ParseResult<S extends Partial<Subcommand>[]> = {\n [K in keyof S]: Prettify<\n { subcommand: S[K][\"name\"] } & Positional<S[K]> &\n Info<S[K][\"options\"]> &\n OptionsArr2RecordType<S[K][\"options\"]> &\n ArgumentsArr2ArrType<S[K][\"arguments\"]>\n >;\n}[number];\n\nexport type PrintMethods<N extends Subcommand[\"name\"] | undefined> = {\n printCliHelp: (options?: PrintHelpOpt) => void;\n printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;\n};\n\nexport type UnSafeParseResult<S extends Partial<Subcommand>[]> = Prettify<\n ParseResult<S> & PrintMethods<S[number][\"name\"]>\n>;\n\nexport type SafeParseResult<S extends Partial<Subcommand>[]> = Prettify<\n ({ success: false; error: Error } | { success: true; data: ParseResult<S> }) & PrintMethods<S[number][\"name\"]>\n>;\n\nexport type ActionFn<T extends Subcommand | Cli> = {\n setAction: (actions: (res: UnSafeParseResult<[T]>) => void) => void;\n};\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"sourcesContent":["import type { z } from \"zod\";\n\nexport type Subcommand = {\n /**\n * - The subcommand name, use `kebab-case`.\n * - Make sure to not duplicate commands and aliases.\n *\n * @example\n * name: \"test\";\n * name: \"run-app\";\n */\n name: string;\n\n /**\n * - The action is executed with the result of the parsed arguments.\n * - To get typescript types use `setAction` instead of this.\n *\n * @example\n * const helpCommand = createSubcommand({ name: \"help\", options: [...] });\n * helpCommand.setAction(res => console.log(res));\n */\n action?: (results?: any) => void;\n\n /**\n * - The description of the subcommand.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - Provide an example to show to the user.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the subcommand.\n * - Make sure to not duplicate aliases and commands.\n */\n aliases?: string[];\n\n /**\n * - Allows positional arguments for this subcommand.\n * - Unlike `arguments`, which are strictly typed, positional arguments are untyped and represented as a string array of\n * variable length.\n * - When enabled and `arguments` are provided, `arguments` will be parsed first. Any remaining arguments will be\n * considered positional arguments and added to the `positional` property in the result.\n */\n allowPositional?: boolean;\n\n /**\n * - The options of the command.\n * - Those options are specific to this subcommand.\n */\n options?: [Option, ...Option[]];\n\n /**\n * - Specifies a list of strictly typed arguments.\n * - The order is important; for example, the first argument will be validated against the first specified type.\n * - It is recommended to not use optional arguments as the parser will fill the arguments by order and can't determine\n * which arguments are optional.\n */\n arguments?: [Argument, ...Argument[]];\n};\n\nexport type Cli = Prettify<\n Omit<Subcommand, \"name\"> & {\n /** - The name of the CLI program. */\n cliName: string;\n\n /**\n * - The usage of the CLI program.\n * - Used for generating the help message.\n */\n usage?: string;\n }\n>;\n\nexport type Option = {\n /**\n * - The name of the option, use `CamelCase`.\n * - For example: the syntax for the option `rootPath` is `--root-path`.\n */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean().default(false);\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(parseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the option.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - The example of using the option.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the option, use `CamelCase`.\n * - Here you can specify short names or flags.\n * - Make sure to not duplicate aliases.\n */\n aliases?: [string, ...string[]];\n};\n\nexport type Argument = {\n /** - The name of the argument. */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean();\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(ParseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the argument.\n * - Used for generating the help message.\n */\n description?: string;\n\n /**\n * - The example of using the argument.\n * - Used for generating the help message.\n */\n example?: string;\n};\n\nexport type ColorFnType = (...text: unknown[]) => string;\n\nexport type PrintHelpOpt = {\n /**\n * - **Optional** `boolean`\n * - Whether to print colors or not.\n * - Default: `true`\n */\n colors?: boolean;\n\n /**\n * - **Optional** `object`\n * - The colors to use for the help message.\n */\n customColors?: {\n title?: ColorFnType;\n description?: ColorFnType;\n default?: ColorFnType;\n optional?: ColorFnType;\n exampleTitle?: ColorFnType;\n example?: ColorFnType;\n command?: ColorFnType;\n option?: ColorFnType;\n argument?: ColorFnType;\n placeholder?: ColorFnType;\n punctuation?: ColorFnType;\n };\n};\n\nexport type _Info = {\n /**\n * - The raw argument as it was passed in\n * - For options that have a default value and are not passed in, the raw argument will be `undefined`\n */\n rawArg?: string;\n /**\n * - The raw value of the argument as it was passed in\n * - It will be empty string for `boolean` options. E.g. `--help` or `-h`\n * - For options that have a default value and are not passed in, the raw value will be `undefined`\n */\n rawValue?: string;\n /**\n * - The source value of the argument:\n * - `cli`: The argument was passed in by the user\n * - `default`: The argument was not passed in and has a default value\n */\n source: \"cli\" | \"default\";\n};\n\n/**\n * - Infer the options type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", options: [...] });\n * type OptionsType = InferOptionsType<typeof subcommand>;\n */\nexport type InferOptionsType<T extends Partial<Subcommand>> = T[\"options\"] extends infer U extends Option[]\n ? ToOptional<{ [K in U[number][\"name\"]]: z.infer<Extract<U[number], { name: K }>[\"type\"]> }>\n : undefined;\n\n/**\n * - Infer the arguments type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", arguments: [...] });\n * type ArgumentsType = InferArgumentsType<typeof subcommand>;\n */\nexport type InferArgumentsType<T extends Partial<Subcommand>> = T[\"arguments\"] extends infer U extends Argument[]\n ? { [K in keyof U]: U[K] extends { type: z.ZodTypeAny } ? z.infer<U[K][\"type\"]> : never }\n : undefined;\n\n/** `{ some props } & { other props }` => `{ some props, other props }` */\nexport type Prettify<T> = { [K in keyof T]: T[K] } & {};\n\n/** Allow string type for literal union and get auto completion */\nexport type LiteralUnion<T extends string> = T | (string & {});\n\n/** Extract the undefined properties from an object */\ntype UndefinedProperties<T> = { [P in keyof T]-?: undefined extends T[P] ? P : never }[keyof T];\n\n/** Make undefined properties optional? */\ntype ToOptional<T> = Prettify<\n Partial<Pick<T, UndefinedProperties<T>>> & Pick<T, Exclude<keyof T, UndefinedProperties<T>>>\n>;\n\nexport type OptionsArr2RecordType<T extends Option[] | undefined> = T extends Option[]\n ? ToOptional<{ [K in T[number][\"name\"]]: z.infer<Extract<T[number], { name: K }>[\"type\"]> }>\n : object;\n\nexport type ArgumentsArr2ArrType<T extends Argument[] | undefined> = T extends Argument[]\n ? { arguments: { [K in keyof T]: T[K] extends { type: z.ZodTypeAny } ? z.infer<T[K][\"type\"]> : never } }\n : object;\n\nexport type Positional<S extends Partial<Subcommand>> = S[\"allowPositional\"] extends true\n ? { positional: string[] }\n : object;\n\nexport type Info<T extends Option[] | undefined> = T extends Option[]\n ? {\n _info: ToOptional<{\n [K in T[number][\"name\"]]: Extract<T[number], { name: K }> extends infer U extends Option\n ? undefined extends z.infer<U[\"type\"]>\n ? undefined | Prettify<_Info & U> // if optional add undefined\n : Prettify<_Info & U>\n : never;\n }>;\n }\n : object;\n\nexport type NoSubcommand = { name: undefined };\n\nexport type ParseResult<S extends Partial<Subcommand>[]> = {\n [K in keyof S]: Prettify<\n { subcommand: S[K][\"name\"] } & Positional<S[K]> &\n Info<S[K][\"options\"]> &\n OptionsArr2RecordType<S[K][\"options\"]> &\n ArgumentsArr2ArrType<S[K][\"arguments\"]>\n >;\n}[number];\n\nexport type PrintMethods<N extends Subcommand[\"name\"] | undefined> = {\n printCliHelp: (options?: PrintHelpOpt) => void;\n printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;\n};\n\nexport type UnSafeParseResult<S extends Partial<Subcommand>[]> =\n CheckDuplicatedSubcommands<S> extends infer E extends string\n ? E\n : Prettify<ParseResult<S> & PrintMethods<S[number][\"name\"]>>;\n\nexport type SafeParseResult<S extends Partial<Subcommand>[]> =\n CheckDuplicatedSubcommands<S> extends infer E extends string\n ? E\n : Prettify<\n ({ success: false; error: Error } | { success: true; data: ParseResult<S> }) & PrintMethods<S[number][\"name\"]>\n >;\n\nexport type ActionFn<T extends Subcommand | Cli> = {\n setAction: (actions: (res: UnSafeParseResult<[T]>) => void) => void;\n};\n\n/** - Combine `name` and `aliases` to a `string[]` */\ntype MapNameAndAliases2StrArr<T extends { name?: string; aliases?: string[] }[]> = T extends [\n infer First extends Subcommand,\n ...infer Rest,\n]\n ? Rest extends { name?: string; aliases?: string[] }[]\n ? [First[\"name\"], ...(First[\"aliases\"] extends string[] ? First[\"aliases\"] : []), ...MapNameAndAliases2StrArr<Rest>]\n : [First[\"name\"], ...(First[\"aliases\"] extends string[] ? First[\"aliases\"] : [])]\n : [];\n\n/**\n * - Find duplicated items in an array and return it\n * - Return `false` if not found\n */\ntype IsDuplicatesInArr<Input extends any[]> = Input extends [infer Item, ...infer Rest]\n ? Rest extends any[]\n ? Item extends Rest[number]\n ? Item\n : IsDuplicatesInArr<Rest>\n : false\n : false;\n\n/**\n * - Check if there are duplicated options including aliases in `subcommand`\n * - Return an error message if duplicated is found\n * - Return `subcommand` if not found\n */\nexport type CheckDuplicatedOptions<T extends Subcommand | Cli> = T[\"options\"] extends infer O extends Option[]\n ? IsDuplicatesInArr<MapNameAndAliases2StrArr<O>> extends infer D extends string\n ? `>>> Error: Duplicated Options \\`${D}\\` <<<`\n : T\n : T;\n\n/**\n * - Check for duplicated subcommands including aliases\n * - Return an error message if duplicated is found\n * - Return the `subcommand[]` if no error\n */\nexport type CheckDuplicatedSubcommands<T extends Partial<Subcommand>[]> =\n IsDuplicatesInArr<MapNameAndAliases2StrArr<T>> extends infer D extends string\n ? `>>> Error: Duplicated Subcommand \\`${D}\\` <<<`\n : T;\n"],"mappings":"","ignoreList":[]}
|
package/lib/module/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{help}from"./help.js";import{parse,safeParse}from"./parser.js";function createSubcommand(input){return Object.assign(input,{setAction:action=>input.action=action});}function createCli(input){return Object.assign(input,{setAction:action=>input.action=action});}const{printCliHelp,printSubcommandHelp}=help;export{createCli,createSubcommand,parse,printCliHelp,printSubcommandHelp,safeParse};
|
|
1
|
+
import{help}from"./help.js";import{parse,safeParse}from"./parser.js";function createSubcommand(input){return Object.assign(input,{setAction:action=>input.action=action});}function createCli(input){return Object.assign(input,{setAction:action=>input.action=action});}function createOptions(options){return options;}const{printCliHelp,printSubcommandHelp}=help;export{createCli,createSubcommand,createOptions,parse,printCliHelp,printSubcommandHelp,safeParse};
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["help","parse","safeParse","createSubcommand","input","Object","assign","setAction","action","createCli","printCliHelp","printSubcommandHelp"],"sourceRoot":"../../src","sources":["index.ts"],"sourcesContent":["import { help } from \"./help.js\";\nimport { parse, safeParse } from \"./parser.js\";\n\nimport type {
|
|
1
|
+
{"version":3,"names":["help","parse","safeParse","createSubcommand","input","Object","assign","setAction","action","createCli","createOptions","options","printCliHelp","printSubcommandHelp"],"sourceRoot":"../../src","sources":["index.ts"],"sourcesContent":["import { help } from \"./help.js\";\nimport { parse, safeParse } from \"./parser.js\";\n\nimport type {\n ActionFn,\n CheckDuplicatedOptions,\n Cli,\n Option,\n Prettify,\n Subcommand,\n UnSafeParseResult,\n} from \"./types.js\";\n\nfunction createSubcommand<const T extends Subcommand>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>> {\n return Object.assign(input, {\n setAction: (action: (res: UnSafeParseResult<[T]>) => void) => (input.action = action),\n });\n}\n\nfunction createCli<const T extends Cli>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>> {\n return Object.assign(input, {\n setAction: (action: (res: UnSafeParseResult<[T]>) => void) => (input.action = action),\n });\n}\n\nfunction createOptions<const T extends [Option, ...Option[]]>(options: T): T {\n return options;\n}\n\nconst { printCliHelp, printSubcommandHelp } = help;\n\nexport { createCli, createSubcommand, createOptions, parse, printCliHelp, printSubcommandHelp, safeParse };\n\nexport type * from \"./types.js\";\n"],"mappings":"AAAA,OAASA,IAAI,KAAQ,WAAW,CAChC,OAASC,KAAK,CAAEC,SAAS,KAAQ,aAAa,CAY9C,QAAS,CAAAC,gBAAgBA,CAA6BC,KAAgC,CAA6B,CACjH,MAAO,CAAAC,MAAM,CAACC,MAAM,CAACF,KAAK,CAAE,CAC1BG,SAAS,CAAGC,MAA6C,EAAMJ,KAAK,CAACI,MAAM,CAAGA,MAChF,CAAC,CAAC,CACJ,CAEA,QAAS,CAAAC,SAASA,CAAsBL,KAAgC,CAA6B,CACnG,MAAO,CAAAC,MAAM,CAACC,MAAM,CAACF,KAAK,CAAE,CAC1BG,SAAS,CAAGC,MAA6C,EAAMJ,KAAK,CAACI,MAAM,CAAGA,MAChF,CAAC,CAAC,CACJ,CAEA,QAAS,CAAAE,aAAaA,CAAwCC,OAAU,CAAK,CAC3E,MAAO,CAAAA,OAAO,CAChB,CAEA,KAAM,CAAEC,YAAY,CAAEC,mBAAoB,CAAC,CAAGb,IAAI,CAElD,OAASS,SAAS,CAAEN,gBAAgB,CAAEO,aAAa,CAAET,KAAK,CAAEW,YAAY,CAAEC,mBAAmB,CAAEX,SAAS","ignoreList":[]}
|
package/lib/module/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"sourcesContent":["import type { z } from \"zod\";\n\nexport type Subcommand = {\n /**\n * - The subcommand name, use `kebab-case`.\n * - Make sure to not duplicate commands and aliases.\n *\n * @example\n * name: \"test\";\n * name: \"run-app\";\n */\n name: string;\n\n /**\n * - The action is executed with the result of the parsed arguments.\n * - To get typescript types use `setAction` instead of this.\n *\n * @example\n * const helpCommand = createSubcommand({ name: \"help\", options: [...] });\n * helpCommand.setAction(res => console.log(res));\n */\n action?: (results?: any) => void;\n\n /**\n * - The description of the subcommand.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - Provide an example to show to the user.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the subcommand.\n * - Make sure to not duplicate aliases and commands.\n */\n aliases?: string[];\n\n /**\n * - Allows positional arguments for this subcommand.\n * - Unlike `arguments`, which are strictly typed, positional arguments are untyped and represented as a string array of\n * variable length.\n * - When enabled and `arguments` are provided, `arguments` will be parsed first. Any remaining arguments will be\n * considered positional arguments and added to the `positional` property in the result.\n */\n allowPositional?: boolean;\n\n /**\n * - The options of the command.\n * - Those options are specific to this subcommand.\n */\n options?: [Option, ...Option[]];\n\n /**\n * - Specifies a list of strictly typed arguments.\n * - The order is important; for example, the first argument will be validated against the first specified type.\n * - It is recommended to not use optional arguments as the parser will fill the arguments by order and can't determine\n * which arguments are optional.\n */\n arguments?: [Argument, ...Argument[]];\n};\n\nexport type Cli = Prettify<\n Omit<Subcommand, \"name\"> & {\n /** - The name of the CLI program. */\n cliName: string;\n\n /**\n * - The usage of the CLI program.\n * - Used for generating the help message.\n */\n usage?: string;\n }\n>;\n\nexport type Option = {\n /**\n * - The name of the option, use `CamelCase`.\n * - For example: the syntax for the option `rootPath` is `--root-path`.\n */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean().default(false);\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(parseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the option.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - The example of using the option.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the option, use `CamelCase`.\n * - Here you can specify short names or flags.\n * - Make sure to not duplicate aliases.\n */\n aliases?: [string, ...string[]];\n};\n\nexport type Argument = {\n /** - The name of the argument. */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean();\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(ParseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the argument.\n * - Used for generating the help message.\n */\n description?: string;\n\n /**\n * - The example of using the argument.\n * - Used for generating the help message.\n */\n example?: string;\n};\n\nexport type ColorFnType = (...text: unknown[]) => string;\n\nexport type PrintHelpOpt = {\n /**\n * - **Optional** `boolean`\n * - Whether to print colors or not.\n * - Default: `true`\n */\n colors?: boolean;\n\n /**\n * - **Optional** `object`\n * - The colors to use for the help message.\n */\n customColors?: {\n title?: ColorFnType;\n description?: ColorFnType;\n default?: ColorFnType;\n optional?: ColorFnType;\n exampleTitle?: ColorFnType;\n example?: ColorFnType;\n command?: ColorFnType;\n option?: ColorFnType;\n argument?: ColorFnType;\n placeholder?: ColorFnType;\n punctuation?: ColorFnType;\n };\n};\n\nexport type _Info = {\n /**\n * - The raw argument as it was passed in\n * - For options that have a default value and are not passed in, the raw argument will be `undefined`\n */\n rawArg?: string;\n /**\n * - The raw value of the argument as it was passed in\n * - It will be empty string for `boolean` options. E.g. `--help` or `-h`\n * - For options that have a default value and are not passed in, the raw value will be `undefined`\n */\n rawValue?: string;\n /**\n * - The source value of the argument:\n * - `cli`: The argument was passed in by the user\n * - `default`: The argument was not passed in and has a default value\n */\n source: \"cli\" | \"default\";\n};\n\n/**\n * - Infer the options type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", options: [...] });\n * type OptionsType = InferOptionsType<typeof subcommand>;\n */\nexport type InferOptionsType<T extends Partial<Subcommand>> = T[\"options\"] extends infer U extends Option[]\n ? ToOptional<{ [K in U[number][\"name\"]]: z.infer<Extract<U[number], { name: K }>[\"type\"]> }>\n : undefined;\n\n/**\n * - Infer the arguments type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", arguments: [...] });\n * type ArgumentsType = InferArgumentsType<typeof subcommand>;\n */\nexport type InferArgumentsType<T extends Partial<Subcommand>> = T[\"arguments\"] extends infer U extends Argument[]\n ? { [K in keyof U]: U[K] extends { type: z.ZodTypeAny } ? z.infer<U[K][\"type\"]> : never }\n : undefined;\n\n/** `{ some props } & { other props }` => `{ some props, other props }` */\nexport type Prettify<T> = { [K in keyof T]: T[K] } & {};\n\n/** Allow string type for literal union and get auto completion */\nexport type LiteralUnion<T extends string> = T | (string & {});\n\n/** Extract the undefined properties from an object */\ntype UndefinedProperties<T> = { [P in keyof T]-?: undefined extends T[P] ? P : never }[keyof T];\n\n/** Make undefined properties optional? */\ntype ToOptional<T> = Prettify<\n Partial<Pick<T, UndefinedProperties<T>>> & Pick<T, Exclude<keyof T, UndefinedProperties<T>>>\n>;\n\nexport type OptionsArr2RecordType<T extends Option[] | undefined> = T extends Option[]\n ? ToOptional<{ [K in T[number][\"name\"]]: z.infer<Extract<T[number], { name: K }>[\"type\"]> }>\n : object;\n\nexport type ArgumentsArr2ArrType<T extends Argument[] | undefined> = T extends Argument[]\n ? { arguments: { [K in keyof T]: T[K] extends { type: z.ZodTypeAny } ? z.infer<T[K][\"type\"]> : never } }\n : object;\n\nexport type Positional<S extends Partial<Subcommand>> = S[\"allowPositional\"] extends true ? { positional: string[] } : object;\n\nexport type Info<T extends Option[] | undefined> = T extends Option[]\n ? {\n _info: ToOptional<{\n [K in T[number][\"name\"]]: Extract<T[number], { name: K }> extends infer U extends Option\n ? undefined extends z.infer<U[\"type\"]>\n ? undefined | Prettify<_Info & U> // if optional add undefined\n : Prettify<_Info & U>\n : never;\n }>;\n }\n : object;\n\nexport type NoSubcommand = { name: undefined };\n\nexport type ParseResult<S extends Partial<Subcommand>[]> = {\n [K in keyof S]: Prettify<\n { subcommand: S[K][\"name\"] } & Positional<S[K]> &\n Info<S[K][\"options\"]> &\n OptionsArr2RecordType<S[K][\"options\"]> &\n ArgumentsArr2ArrType<S[K][\"arguments\"]>\n >;\n}[number];\n\nexport type PrintMethods<N extends Subcommand[\"name\"] | undefined> = {\n printCliHelp: (options?: PrintHelpOpt) => void;\n printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;\n};\n\nexport type UnSafeParseResult<S extends Partial<Subcommand>[]> = Prettify<\n ParseResult<S> & PrintMethods<S[number][\"name\"]>\n>;\n\nexport type SafeParseResult<S extends Partial<Subcommand>[]> = Prettify<\n ({ success: false; error: Error } | { success: true; data: ParseResult<S> }) & PrintMethods<S[number][\"name\"]>\n>;\n\nexport type ActionFn<T extends Subcommand | Cli> = {\n setAction: (actions: (res: UnSafeParseResult<[T]>) => void) => void;\n};\n"],"mappings":"","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["types.ts"],"sourcesContent":["import type { z } from \"zod\";\n\nexport type Subcommand = {\n /**\n * - The subcommand name, use `kebab-case`.\n * - Make sure to not duplicate commands and aliases.\n *\n * @example\n * name: \"test\";\n * name: \"run-app\";\n */\n name: string;\n\n /**\n * - The action is executed with the result of the parsed arguments.\n * - To get typescript types use `setAction` instead of this.\n *\n * @example\n * const helpCommand = createSubcommand({ name: \"help\", options: [...] });\n * helpCommand.setAction(res => console.log(res));\n */\n action?: (results?: any) => void;\n\n /**\n * - The description of the subcommand.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - Provide an example to show to the user.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the subcommand.\n * - Make sure to not duplicate aliases and commands.\n */\n aliases?: string[];\n\n /**\n * - Allows positional arguments for this subcommand.\n * - Unlike `arguments`, which are strictly typed, positional arguments are untyped and represented as a string array of\n * variable length.\n * - When enabled and `arguments` are provided, `arguments` will be parsed first. Any remaining arguments will be\n * considered positional arguments and added to the `positional` property in the result.\n */\n allowPositional?: boolean;\n\n /**\n * - The options of the command.\n * - Those options are specific to this subcommand.\n */\n options?: [Option, ...Option[]];\n\n /**\n * - Specifies a list of strictly typed arguments.\n * - The order is important; for example, the first argument will be validated against the first specified type.\n * - It is recommended to not use optional arguments as the parser will fill the arguments by order and can't determine\n * which arguments are optional.\n */\n arguments?: [Argument, ...Argument[]];\n};\n\nexport type Cli = Prettify<\n Omit<Subcommand, \"name\"> & {\n /** - The name of the CLI program. */\n cliName: string;\n\n /**\n * - The usage of the CLI program.\n * - Used for generating the help message.\n */\n usage?: string;\n }\n>;\n\nexport type Option = {\n /**\n * - The name of the option, use `CamelCase`.\n * - For example: the syntax for the option `rootPath` is `--root-path`.\n */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean().default(false);\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(parseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the option.\n * - Used for generating the help message.\n */\n description?: string;\n\n /** - Used for generating the help message. */\n placeholder?: string;\n\n /**\n * - The example of using the option.\n * - Used for generating the help message.\n */\n example?: string;\n\n /**\n * - The aliases of the option, use `CamelCase`.\n * - Here you can specify short names or flags.\n * - Make sure to not duplicate aliases.\n */\n aliases?: [string, ...string[]];\n};\n\nexport type Argument = {\n /** - The name of the argument. */\n name: string;\n\n /**\n * - The will be used to validate the user input.\n *\n * @example\n * type: z.boolean();\n * type: z.coerce.number(); // will be coerced to number by Zod\n * type: z.preprocess(ParseStringToArrFn, z.array(z.coerce.number())); // array of numbers\n *\n * @see https://zod.dev/?id=types\n */\n type: z.ZodTypeAny;\n\n /**\n * - The description of the argument.\n * - Used for generating the help message.\n */\n description?: string;\n\n /**\n * - The example of using the argument.\n * - Used for generating the help message.\n */\n example?: string;\n};\n\nexport type ColorFnType = (...text: unknown[]) => string;\n\nexport type PrintHelpOpt = {\n /**\n * - **Optional** `boolean`\n * - Whether to print colors or not.\n * - Default: `true`\n */\n colors?: boolean;\n\n /**\n * - **Optional** `object`\n * - The colors to use for the help message.\n */\n customColors?: {\n title?: ColorFnType;\n description?: ColorFnType;\n default?: ColorFnType;\n optional?: ColorFnType;\n exampleTitle?: ColorFnType;\n example?: ColorFnType;\n command?: ColorFnType;\n option?: ColorFnType;\n argument?: ColorFnType;\n placeholder?: ColorFnType;\n punctuation?: ColorFnType;\n };\n};\n\nexport type _Info = {\n /**\n * - The raw argument as it was passed in\n * - For options that have a default value and are not passed in, the raw argument will be `undefined`\n */\n rawArg?: string;\n /**\n * - The raw value of the argument as it was passed in\n * - It will be empty string for `boolean` options. E.g. `--help` or `-h`\n * - For options that have a default value and are not passed in, the raw value will be `undefined`\n */\n rawValue?: string;\n /**\n * - The source value of the argument:\n * - `cli`: The argument was passed in by the user\n * - `default`: The argument was not passed in and has a default value\n */\n source: \"cli\" | \"default\";\n};\n\n/**\n * - Infer the options type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", options: [...] });\n * type OptionsType = InferOptionsType<typeof subcommand>;\n */\nexport type InferOptionsType<T extends Partial<Subcommand>> = T[\"options\"] extends infer U extends Option[]\n ? ToOptional<{ [K in U[number][\"name\"]]: z.infer<Extract<U[number], { name: K }>[\"type\"]> }>\n : undefined;\n\n/**\n * - Infer the arguments type from a subcommand.\n *\n * @example\n * const subcommand = createSubcommand({ name: \"build\", arguments: [...] });\n * type ArgumentsType = InferArgumentsType<typeof subcommand>;\n */\nexport type InferArgumentsType<T extends Partial<Subcommand>> = T[\"arguments\"] extends infer U extends Argument[]\n ? { [K in keyof U]: U[K] extends { type: z.ZodTypeAny } ? z.infer<U[K][\"type\"]> : never }\n : undefined;\n\n/** `{ some props } & { other props }` => `{ some props, other props }` */\nexport type Prettify<T> = { [K in keyof T]: T[K] } & {};\n\n/** Allow string type for literal union and get auto completion */\nexport type LiteralUnion<T extends string> = T | (string & {});\n\n/** Extract the undefined properties from an object */\ntype UndefinedProperties<T> = { [P in keyof T]-?: undefined extends T[P] ? P : never }[keyof T];\n\n/** Make undefined properties optional? */\ntype ToOptional<T> = Prettify<\n Partial<Pick<T, UndefinedProperties<T>>> & Pick<T, Exclude<keyof T, UndefinedProperties<T>>>\n>;\n\nexport type OptionsArr2RecordType<T extends Option[] | undefined> = T extends Option[]\n ? ToOptional<{ [K in T[number][\"name\"]]: z.infer<Extract<T[number], { name: K }>[\"type\"]> }>\n : object;\n\nexport type ArgumentsArr2ArrType<T extends Argument[] | undefined> = T extends Argument[]\n ? { arguments: { [K in keyof T]: T[K] extends { type: z.ZodTypeAny } ? z.infer<T[K][\"type\"]> : never } }\n : object;\n\nexport type Positional<S extends Partial<Subcommand>> = S[\"allowPositional\"] extends true\n ? { positional: string[] }\n : object;\n\nexport type Info<T extends Option[] | undefined> = T extends Option[]\n ? {\n _info: ToOptional<{\n [K in T[number][\"name\"]]: Extract<T[number], { name: K }> extends infer U extends Option\n ? undefined extends z.infer<U[\"type\"]>\n ? undefined | Prettify<_Info & U> // if optional add undefined\n : Prettify<_Info & U>\n : never;\n }>;\n }\n : object;\n\nexport type NoSubcommand = { name: undefined };\n\nexport type ParseResult<S extends Partial<Subcommand>[]> = {\n [K in keyof S]: Prettify<\n { subcommand: S[K][\"name\"] } & Positional<S[K]> &\n Info<S[K][\"options\"]> &\n OptionsArr2RecordType<S[K][\"options\"]> &\n ArgumentsArr2ArrType<S[K][\"arguments\"]>\n >;\n}[number];\n\nexport type PrintMethods<N extends Subcommand[\"name\"] | undefined> = {\n printCliHelp: (options?: PrintHelpOpt) => void;\n printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;\n};\n\nexport type UnSafeParseResult<S extends Partial<Subcommand>[]> =\n CheckDuplicatedSubcommands<S> extends infer E extends string\n ? E\n : Prettify<ParseResult<S> & PrintMethods<S[number][\"name\"]>>;\n\nexport type SafeParseResult<S extends Partial<Subcommand>[]> =\n CheckDuplicatedSubcommands<S> extends infer E extends string\n ? E\n : Prettify<\n ({ success: false; error: Error } | { success: true; data: ParseResult<S> }) & PrintMethods<S[number][\"name\"]>\n >;\n\nexport type ActionFn<T extends Subcommand | Cli> = {\n setAction: (actions: (res: UnSafeParseResult<[T]>) => void) => void;\n};\n\n/** - Combine `name` and `aliases` to a `string[]` */\ntype MapNameAndAliases2StrArr<T extends { name?: string; aliases?: string[] }[]> = T extends [\n infer First extends Subcommand,\n ...infer Rest,\n]\n ? Rest extends { name?: string; aliases?: string[] }[]\n ? [First[\"name\"], ...(First[\"aliases\"] extends string[] ? First[\"aliases\"] : []), ...MapNameAndAliases2StrArr<Rest>]\n : [First[\"name\"], ...(First[\"aliases\"] extends string[] ? First[\"aliases\"] : [])]\n : [];\n\n/**\n * - Find duplicated items in an array and return it\n * - Return `false` if not found\n */\ntype IsDuplicatesInArr<Input extends any[]> = Input extends [infer Item, ...infer Rest]\n ? Rest extends any[]\n ? Item extends Rest[number]\n ? Item\n : IsDuplicatesInArr<Rest>\n : false\n : false;\n\n/**\n * - Check if there are duplicated options including aliases in `subcommand`\n * - Return an error message if duplicated is found\n * - Return `subcommand` if not found\n */\nexport type CheckDuplicatedOptions<T extends Subcommand | Cli> = T[\"options\"] extends infer O extends Option[]\n ? IsDuplicatesInArr<MapNameAndAliases2StrArr<O>> extends infer D extends string\n ? `>>> Error: Duplicated Options \\`${D}\\` <<<`\n : T\n : T;\n\n/**\n * - Check for duplicated subcommands including aliases\n * - Return an error message if duplicated is found\n * - Return the `subcommand[]` if no error\n */\nexport type CheckDuplicatedSubcommands<T extends Partial<Subcommand>[]> =\n IsDuplicatesInArr<MapNameAndAliases2StrArr<T>> extends infer D extends string\n ? `>>> Error: Duplicated Subcommand \\`${D}\\` <<<`\n : T;\n"],"mappings":"","ignoreList":[]}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { parse, safeParse } from "./parser.js";
|
|
2
|
-
import type { ActionFn, Cli, Prettify, Subcommand } from "./types.js";
|
|
3
|
-
declare function createSubcommand<const T extends Subcommand>(input: T
|
|
4
|
-
declare function createCli<const T extends Cli>(input: T
|
|
2
|
+
import type { ActionFn, CheckDuplicatedOptions, Cli, Option, Prettify, Subcommand } from "./types.js";
|
|
3
|
+
declare function createSubcommand<const T extends Subcommand>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>>;
|
|
4
|
+
declare function createCli<const T extends Cli>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>>;
|
|
5
|
+
declare function createOptions<const T extends [Option, ...Option[]]>(options: T): T;
|
|
5
6
|
declare const printCliHelp: (params: [Cli, ...Subcommand[]], printOptions?: import("./types.js").PrintHelpOpt) => void, printSubcommandHelp: (subcommand: Subcommand, printOptions?: import("./types.js").PrintHelpOpt, cliName?: string) => void;
|
|
6
|
-
export { createCli, createSubcommand, parse, printCliHelp, printSubcommandHelp, safeParse };
|
|
7
|
+
export { createCli, createSubcommand, createOptions, parse, printCliHelp, printSubcommandHelp, safeParse };
|
|
7
8
|
export type * from "./types.js";
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EACV,QAAQ,EACR,sBAAsB,EACtB,GAAG,EACH,MAAM,EACN,QAAQ,EACR,UAAU,EAEX,MAAM,YAAY,CAAC;AAEpB,iBAAS,gBAAgB,CAAC,KAAK,CAAC,CAAC,SAAS,UAAU,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAIjH;AAED,iBAAS,SAAS,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,EAAE,KAAK,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAInG;AAED,iBAAS,aAAa,CAAC,KAAK,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,CAAC,CAE3E;AAED,QAAA,MAAQ,YAAY,8FAAE,mBAAmB,sGAAS,CAAC;AAEnD,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,CAAC;AAE3G,mBAAmB,YAAY,CAAC"}
|
|
@@ -241,8 +241,8 @@ export type PrintMethods<N extends Subcommand["name"] | undefined> = {
|
|
|
241
241
|
printCliHelp: (options?: PrintHelpOpt) => void;
|
|
242
242
|
printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;
|
|
243
243
|
};
|
|
244
|
-
export type UnSafeParseResult<S extends Partial<Subcommand>[]> = Prettify<ParseResult<S> & PrintMethods<S[number]["name"]>>;
|
|
245
|
-
export type SafeParseResult<S extends Partial<Subcommand>[]> = Prettify<({
|
|
244
|
+
export type UnSafeParseResult<S extends Partial<Subcommand>[]> = CheckDuplicatedSubcommands<S> extends infer E extends string ? E : Prettify<ParseResult<S> & PrintMethods<S[number]["name"]>>;
|
|
245
|
+
export type SafeParseResult<S extends Partial<Subcommand>[]> = CheckDuplicatedSubcommands<S> extends infer E extends string ? E : Prettify<({
|
|
246
246
|
success: false;
|
|
247
247
|
error: Error;
|
|
248
248
|
} | {
|
|
@@ -252,5 +252,33 @@ export type SafeParseResult<S extends Partial<Subcommand>[]> = Prettify<({
|
|
|
252
252
|
export type ActionFn<T extends Subcommand | Cli> = {
|
|
253
253
|
setAction: (actions: (res: UnSafeParseResult<[T]>) => void) => void;
|
|
254
254
|
};
|
|
255
|
+
/** - Combine `name` and `aliases` to a `string[]` */
|
|
256
|
+
type MapNameAndAliases2StrArr<T extends {
|
|
257
|
+
name?: string;
|
|
258
|
+
aliases?: string[];
|
|
259
|
+
}[]> = T extends [
|
|
260
|
+
infer First extends Subcommand,
|
|
261
|
+
...infer Rest
|
|
262
|
+
] ? Rest extends {
|
|
263
|
+
name?: string;
|
|
264
|
+
aliases?: string[];
|
|
265
|
+
}[] ? [First["name"], ...(First["aliases"] extends string[] ? First["aliases"] : []), ...MapNameAndAliases2StrArr<Rest>] : [First["name"], ...(First["aliases"] extends string[] ? First["aliases"] : [])] : [];
|
|
266
|
+
/**
|
|
267
|
+
* - Find duplicated items in an array and return it
|
|
268
|
+
* - Return `false` if not found
|
|
269
|
+
*/
|
|
270
|
+
type IsDuplicatesInArr<Input extends any[]> = Input extends [infer Item, ...infer Rest] ? Rest extends any[] ? Item extends Rest[number] ? Item : IsDuplicatesInArr<Rest> : false : false;
|
|
271
|
+
/**
|
|
272
|
+
* - Check if there are duplicated options including aliases in `subcommand`
|
|
273
|
+
* - Return an error message if duplicated is found
|
|
274
|
+
* - Return `subcommand` if not found
|
|
275
|
+
*/
|
|
276
|
+
export type CheckDuplicatedOptions<T extends Subcommand | Cli> = T["options"] extends infer O extends Option[] ? IsDuplicatesInArr<MapNameAndAliases2StrArr<O>> extends infer D extends string ? `>>> Error: Duplicated Options \`${D}\` <<<` : T : T;
|
|
277
|
+
/**
|
|
278
|
+
* - Check for duplicated subcommands including aliases
|
|
279
|
+
* - Return an error message if duplicated is found
|
|
280
|
+
* - Return the `subcommand[]` if no error
|
|
281
|
+
*/
|
|
282
|
+
export type CheckDuplicatedSubcommands<T extends Partial<Subcommand>[]> = IsDuplicatesInArr<MapNameAndAliases2StrArr<T>> extends infer D extends string ? `>>> Error: Duplicated Subcommand \`${D}\` <<<` : T;
|
|
255
283
|
export {};
|
|
256
284
|
//# sourceMappingURL=types.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,MAAM,MAAM,UAAU,GAAG;IACvB;;;;;;;OAOG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;OAOG;IACH,MAAM,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,GAAG,KAAK,IAAI,CAAC;IAEjC;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAEhC;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,GAAG,GAAG,QAAQ,CACxB,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,GAAG;IACzB,qCAAqC;IACrC,OAAO,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CACF,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG;IACnB;;;OAGG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;;;OASG;IACH,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC;IAEnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,8CAA8C;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,kCAAkC;IAClC,IAAI,EAAE,MAAM,CAAC;IAEb;;;;;;;;;OASG;IACH,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC;IAEnB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,MAAM,CAAC;AAEzD,MAAM,MAAM,YAAY,GAAG;IACzB;;;;OAIG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,YAAY,CAAC,EAAE;QACb,KAAK,CAAC,EAAE,WAAW,CAAC;QACpB,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,OAAO,CAAC,EAAE,WAAW,CAAC;QACtB,QAAQ,CAAC,EAAE,WAAW,CAAC;QACvB,YAAY,CAAC,EAAE,WAAW,CAAC;QAC3B,OAAO,CAAC,EAAE,WAAW,CAAC;QACtB,OAAO,CAAC,EAAE,WAAW,CAAC;QACtB,MAAM,CAAC,EAAE,WAAW,CAAC;QACrB,QAAQ,CAAC,EAAE,WAAW,CAAC;QACvB,WAAW,CAAC,EAAE,WAAW,CAAC;QAC1B,WAAW,CAAC,EAAE,WAAW,CAAC;KAC3B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;OAIG;IACH,MAAM,EAAE,KAAK,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,SAAS,MAAM,CAAC,SAAS,MAAM,EAAE,GACvG,UAAU,CAAC;KAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC,MAAM,CAAC,CAAC;CAAE,CAAC,GAC1F,SAAS,CAAC;AAEd;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,CAAC,CAAC,SAAS,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,SAAS,MAAM,CAAC,SAAS,QAAQ,EAAE,GAC7G;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAA;KAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK;CAAE,GACvF,SAAS,CAAC;AAEd,0EAA0E;AAC1E,MAAM,MAAM,QAAQ,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,GAAG,EAAE,CAAC;AAExD,kEAAkE;AAClE,MAAM,MAAM,YAAY,CAAC,CAAC,SAAS,MAAM,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAE/D,sDAAsD;AACtD,KAAK,mBAAmB,CAAC,CAAC,IAAI;KAAG,CAAC,IAAI,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK;CAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AAEhG,0CAA0C;AAC1C,KAAK,UAAU,CAAC,CAAC,IAAI,QAAQ,CAC3B,OAAO,CAAC,IAAI,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,CAC7F,CAAC;AAEF,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,IAAI,CAAC,SAAS,MAAM,EAAE,GAClF,UAAU,CAAC;KAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC,MAAM,CAAC,CAAC;CAAE,CAAC,GAC1F,MAAM,CAAC;AAEX,MAAM,MAAM,oBAAoB,CAAC,CAAC,SAAS,QAAQ,EAAE,GAAG,SAAS,IAAI,CAAC,SAAS,QAAQ,EAAE,GACrF;IAAE,SAAS,EAAE;SAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;YAAE,IAAI,EAAE,CAAC,CAAC,UAAU,CAAA;SAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK;KAAE,CAAA;CAAE,GACtG,MAAM,CAAC;AAEX,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,iBAAiB,CAAC,SAAS,IAAI,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod-args-parser",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A strictly typed command-line arguments parser powered by Zod.",
|
|
5
|
+
"author": "Ahmed ALABSI <alabsi91@gmail>",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/alabsi91/zod-args-parser.git"
|
|
10
|
+
},
|
|
5
11
|
"type": "module",
|
|
6
12
|
"scripts": {
|
|
7
13
|
"dev": "tsx watch src/test.ts",
|
|
@@ -24,6 +30,14 @@
|
|
|
24
30
|
"lib",
|
|
25
31
|
"src"
|
|
26
32
|
],
|
|
33
|
+
"keywords": [
|
|
34
|
+
"command-line",
|
|
35
|
+
"cli",
|
|
36
|
+
"arguments",
|
|
37
|
+
"parser",
|
|
38
|
+
"zod",
|
|
39
|
+
"typescript"
|
|
40
|
+
],
|
|
27
41
|
"dependencies": {
|
|
28
42
|
"chalk": "^5.3.0",
|
|
29
43
|
"zod": "^3.23.8"
|
|
@@ -46,4 +60,4 @@
|
|
|
46
60
|
"typescript": "^5.6.3",
|
|
47
61
|
"typescript-eslint": "^8.14.0"
|
|
48
62
|
}
|
|
49
|
-
}
|
|
63
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
1
|
import { help } from "./help.js";
|
|
2
2
|
import { parse, safeParse } from "./parser.js";
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
ActionFn,
|
|
6
|
+
CheckDuplicatedOptions,
|
|
7
|
+
Cli,
|
|
8
|
+
Option,
|
|
9
|
+
Prettify,
|
|
10
|
+
Subcommand,
|
|
11
|
+
UnSafeParseResult,
|
|
12
|
+
} from "./types.js";
|
|
5
13
|
|
|
6
|
-
function createSubcommand<const T extends Subcommand>(input: T
|
|
14
|
+
function createSubcommand<const T extends Subcommand>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>> {
|
|
7
15
|
return Object.assign(input, {
|
|
8
16
|
setAction: (action: (res: UnSafeParseResult<[T]>) => void) => (input.action = action),
|
|
9
17
|
});
|
|
10
18
|
}
|
|
11
19
|
|
|
12
|
-
function createCli<const T extends Cli>(input: T
|
|
20
|
+
function createCli<const T extends Cli>(input: CheckDuplicatedOptions<T>): Prettify<T & ActionFn<T>> {
|
|
13
21
|
return Object.assign(input, {
|
|
14
22
|
setAction: (action: (res: UnSafeParseResult<[T]>) => void) => (input.action = action),
|
|
15
23
|
});
|
|
16
24
|
}
|
|
17
25
|
|
|
26
|
+
function createOptions<const T extends [Option, ...Option[]]>(options: T): T {
|
|
27
|
+
return options;
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
const { printCliHelp, printSubcommandHelp } = help;
|
|
19
31
|
|
|
20
|
-
export { createCli, createSubcommand, parse, printCliHelp, printSubcommandHelp, safeParse };
|
|
32
|
+
export { createCli, createSubcommand, createOptions, parse, printCliHelp, printSubcommandHelp, safeParse };
|
|
21
33
|
|
|
22
34
|
export type * from "./types.js";
|
package/src/types.ts
CHANGED
|
@@ -243,7 +243,9 @@ export type ArgumentsArr2ArrType<T extends Argument[] | undefined> = T extends A
|
|
|
243
243
|
? { arguments: { [K in keyof T]: T[K] extends { type: z.ZodTypeAny } ? z.infer<T[K]["type"]> : never } }
|
|
244
244
|
: object;
|
|
245
245
|
|
|
246
|
-
export type Positional<S extends Partial<Subcommand>> = S["allowPositional"] extends true
|
|
246
|
+
export type Positional<S extends Partial<Subcommand>> = S["allowPositional"] extends true
|
|
247
|
+
? { positional: string[] }
|
|
248
|
+
: object;
|
|
247
249
|
|
|
248
250
|
export type Info<T extends Option[] | undefined> = T extends Option[]
|
|
249
251
|
? {
|
|
@@ -273,14 +275,61 @@ export type PrintMethods<N extends Subcommand["name"] | undefined> = {
|
|
|
273
275
|
printSubcommandHelp: (subcommand: LiteralUnion<NonNullable<N>>, options?: PrintHelpOpt) => void;
|
|
274
276
|
};
|
|
275
277
|
|
|
276
|
-
export type UnSafeParseResult<S extends Partial<Subcommand>[]> =
|
|
277
|
-
|
|
278
|
-
|
|
278
|
+
export type UnSafeParseResult<S extends Partial<Subcommand>[]> =
|
|
279
|
+
CheckDuplicatedSubcommands<S> extends infer E extends string
|
|
280
|
+
? E
|
|
281
|
+
: Prettify<ParseResult<S> & PrintMethods<S[number]["name"]>>;
|
|
279
282
|
|
|
280
|
-
export type SafeParseResult<S extends Partial<Subcommand>[]> =
|
|
281
|
-
|
|
282
|
-
|
|
283
|
+
export type SafeParseResult<S extends Partial<Subcommand>[]> =
|
|
284
|
+
CheckDuplicatedSubcommands<S> extends infer E extends string
|
|
285
|
+
? E
|
|
286
|
+
: Prettify<
|
|
287
|
+
({ success: false; error: Error } | { success: true; data: ParseResult<S> }) & PrintMethods<S[number]["name"]>
|
|
288
|
+
>;
|
|
283
289
|
|
|
284
290
|
export type ActionFn<T extends Subcommand | Cli> = {
|
|
285
291
|
setAction: (actions: (res: UnSafeParseResult<[T]>) => void) => void;
|
|
286
292
|
};
|
|
293
|
+
|
|
294
|
+
/** - Combine `name` and `aliases` to a `string[]` */
|
|
295
|
+
type MapNameAndAliases2StrArr<T extends { name?: string; aliases?: string[] }[]> = T extends [
|
|
296
|
+
infer First extends Subcommand,
|
|
297
|
+
...infer Rest,
|
|
298
|
+
]
|
|
299
|
+
? Rest extends { name?: string; aliases?: string[] }[]
|
|
300
|
+
? [First["name"], ...(First["aliases"] extends string[] ? First["aliases"] : []), ...MapNameAndAliases2StrArr<Rest>]
|
|
301
|
+
: [First["name"], ...(First["aliases"] extends string[] ? First["aliases"] : [])]
|
|
302
|
+
: [];
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* - Find duplicated items in an array and return it
|
|
306
|
+
* - Return `false` if not found
|
|
307
|
+
*/
|
|
308
|
+
type IsDuplicatesInArr<Input extends any[]> = Input extends [infer Item, ...infer Rest]
|
|
309
|
+
? Rest extends any[]
|
|
310
|
+
? Item extends Rest[number]
|
|
311
|
+
? Item
|
|
312
|
+
: IsDuplicatesInArr<Rest>
|
|
313
|
+
: false
|
|
314
|
+
: false;
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* - Check if there are duplicated options including aliases in `subcommand`
|
|
318
|
+
* - Return an error message if duplicated is found
|
|
319
|
+
* - Return `subcommand` if not found
|
|
320
|
+
*/
|
|
321
|
+
export type CheckDuplicatedOptions<T extends Subcommand | Cli> = T["options"] extends infer O extends Option[]
|
|
322
|
+
? IsDuplicatesInArr<MapNameAndAliases2StrArr<O>> extends infer D extends string
|
|
323
|
+
? `>>> Error: Duplicated Options \`${D}\` <<<`
|
|
324
|
+
: T
|
|
325
|
+
: T;
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* - Check for duplicated subcommands including aliases
|
|
329
|
+
* - Return an error message if duplicated is found
|
|
330
|
+
* - Return the `subcommand[]` if no error
|
|
331
|
+
*/
|
|
332
|
+
export type CheckDuplicatedSubcommands<T extends Partial<Subcommand>[]> =
|
|
333
|
+
IsDuplicatesInArr<MapNameAndAliases2StrArr<T>> extends infer D extends string
|
|
334
|
+
? `>>> Error: Duplicated Subcommand \`${D}\` <<<`
|
|
335
|
+
: T;
|