diff --git a/README.md b/README.md index f579e32..1ca249a 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ [![NPM Version](https://img.shields.io/npm/v/yargs-typebox)](https://www.npmjs.com/package/yargs-typebox) [![NPM Downloads](https://img.shields.io/npm/d18m/yargs-typebox)](https://www.npmjs.com/package/yargs-typebox) -[![Codecov](https://codecov.io/gh/moontai0724/yargs-typebox/graph/badge.svg)](https://codecov.io/gh/moontai0724/yargs-typebox) +[![Codecov](https://codecov.io/gh/moontaiworks/yargs-typebox/graph/badge.svg)](https://codecov.io/gh/moontaiworks/yargs-typebox) -Use [TypeBox](https://github.com/sinclairzx81/typebox) to define your yargs arguments. +Use [TypeBox](https://github.com/sinclairzx81/typebox) to define your [yargs](https://www.npmjs.com/package/yargs) arguments. ## Install @@ -28,12 +28,115 @@ pnpm add yargs-typebox ## Usage +### getOptions(TObject) + +Transform a whole TypeBox object into yargs options object. + +```typescript +import { type Static, Type } from "@sinclair/typebox"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import { getOptions } from "yargs-typebox"; + +const schema = Type.Object({ + page: Type.Number({ description: "page number" }), + size: Type.Number({ description: "page size", default: 10 }), + query: Type.Optional(Type.String()), + sort: Type.Optional( + Type.Array(Type.Union([Type.Literal("id"), Type.Literal("createdAt")])), + ), + order: Type.Union([Type.Literal("asc"), Type.Literal("desc")], { + default: "asc", + implies: ["sort"], + }), + pretty: Type.Boolean({ description: "pretty print" }), + count: Type.Any({ description: "count", count: true }), +}); + +const options = getOptions(schema); +// { +// page: { +// type: "number", +// demandOption: true, +// describe: "page number", +// }, +// size: { +// type: "number", +// default: 10, +// demandOption: false, +// describe: "page size", +// }, +// query: { +// type: "string", +// demandOption: false, +// }, +// sort: { +// type: "array", +// demandOption: false, +// choices: ["id", "createdAt"], +// }, +// order: { +// type: "string", +// implies: ["sort"], +// default: "asc", +// demandOption: false, +// choices: ["asc", "desc"], +// }, +// pretty: { +// type: "boolean", +// demandOption: true, +// describe: "pretty print", +// }, +// count: { +// count: true, +// demandOption: true, +// describe: "count", +// }, +// } + +const argv = yargs(hideBin(process.argv)) + .options(options) + .help() + .parse() as Static; + +console.log(argv); +``` + +### getOption(TSchema) + +Transform a single TypeBox schema into yargs option. + ```typescript -import { ... } from "yargs-typebox"; +import { Type } from "@sinclair/typebox"; +import yargs from "yargs"; +import { hideBin } from "yargs/helpers"; +import { getOption } from "yargs-typebox"; + +const prettyArgument = Type.Boolean({ description: "pretty print" }); +const countArgument = Type.Any({ description: "count", count: true }); + +const prettyOption = getOption(prettyArgument); +// { +// type: "boolean", +// demandOption: true, +// describe: "pretty print", +// } +const countOption = getOption(countArgument); +// { +// count: true, +// demandOption: true, +// describe: "count", +// } + +const argv = yargs(hideBin(process.argv)) + .option("pretty", prettyOption) + .option("count", countOption) + .help() + .parse(); -// TBD +console.log(argv); ``` ## API Document -See the [API documentation](https://moontai0724.github.io/yargs-typebox/). +For more informations, see the [API documentation](https://moontaiworks.github.io/yargs-typebox/). diff --git a/package.json b/package.json index 5e6cde3..88a2766 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "publishConfig": { "access": "public" }, - "version": "0.0.0-pre", + "version": "0.0.0", "description": "Use typebox to define your yargs arguments.", "author": "moontai0724", "license": "MIT", diff --git a/src/get-option.ts b/src/get-option.ts index b71fdbd..6a13270 100644 --- a/src/get-option.ts +++ b/src/get-option.ts @@ -19,6 +19,25 @@ import { getStringOption, } from "./transformers"; +/** + * Handy function to get yargs options from TypeBox schema without having to + * manually call corresponding transformers. + * + * Handlable TypeBox schema types: + * - `TNumber` + * - `TString` + * - `TBoolean` + * - `TArray` + * - `TLiteral` + * - `TUnion` + * + * Schemas that are not supported will still be able to transform, but only pick + * supported yargs properties from schema. + * + * @param schema Any TypeBox schema that could be transformed to yargs options. + * @param overwrites overwrites for yargs options result + * @returns applicable yargs options in schema and overwrites + */ export function getOption( schema: T, overwrites?: O, diff --git a/src/get-options.ts b/src/get-options.ts index f059d3a..c1fe959 100644 --- a/src/get-options.ts +++ b/src/get-options.ts @@ -3,6 +3,17 @@ import type { Options } from "yargs"; import { getOption } from "./get-option"; +/** + * Transform a whole TypeBox TObject schema to multiple yargs options. Key of + * the object will be the name of the parameter, and the value will be the yargs + * option schema. + * + * The value will be transformed by `getOption` function. + * + * @param schema TypeBox TObject schema to transform as multiple yargs options, + * as key be the name and the value be the schema + * @returns transformed object of yargs options + */ export function getOptions( schema: Schema, ): Record, Options> { diff --git a/src/transformers/any.ts b/src/transformers/any.ts index b5cc802..a63b7dc 100644 --- a/src/transformers/any.ts +++ b/src/transformers/any.ts @@ -5,6 +5,8 @@ import type { Options } from "yargs"; * Transform TypeBox schema and options appended in schema to yargs options. * @param type type of the yargs option * @param schema TypeBox schema to transform + * @param overwrites overwrites for yargs options result + * @returns applicable yargs options in schema and overwrites * @see https://yargs.js.org/docs/#api-reference-optionskey-opt */ export function getAnyOption< diff --git a/src/transformers/array.ts b/src/transformers/array.ts index a5962d3..565e0f5 100644 --- a/src/transformers/array.ts +++ b/src/transformers/array.ts @@ -28,6 +28,18 @@ function getChoices(schema: TSchema) { return undefined; } +/** + * Transform TypeBox TArray schema and options appended in schema to yargs + * options. + * + * If the array items is Literal or Union of Literal, the choices will be set to + * the const value of the Literal or Union of Literal. Otherwise, the choices + * will be undefined. + * + * @param schema TypeBox TArray schema to transform + * @param overwrites overwrites for yargs options result + * @returns applicable yargs options in schema and overwrites + */ export function getArrayOption( schema: S, overwrites: O = {} as never, diff --git a/src/transformers/boolean.ts b/src/transformers/boolean.ts index 8c277cc..20ca395 100644 --- a/src/transformers/boolean.ts +++ b/src/transformers/boolean.ts @@ -3,6 +3,14 @@ import type { Options } from "yargs"; import { getAnyOption } from "./any"; +/** + * Transform TypeBox TBoolean schema and options appended in schema to yargs + * options. + * + * @param schema TypeBox TBoolean schema to transform + * @param overwrites overwrites for yargs options result + * @returns applicable yargs options in schema and overwrites + */ export function getBooleanOption< S extends TBoolean, O extends Options = object, diff --git a/src/transformers/choice.ts b/src/transformers/choice.ts index ce19cc2..33ef7ca 100644 --- a/src/transformers/choice.ts +++ b/src/transformers/choice.ts @@ -6,6 +6,14 @@ import { tUnionToTuple } from "@/helpers/t-union-to-tuple"; import { getAnyOption } from "./any"; +/** + * Transform TypeBox TLiteral or TUnion of TLiteral schema and options appended + * in schema to yargs options. + * + * @param schema TypeBox TLiteral or TUnion of TLiteral schema to transform + * @param overwrites overwrites for yargs options result + * @returns applicable yargs options in schema and overwrites + */ export function getChoiceOption< S extends TLiteral | TUnion, O extends Options = object, diff --git a/src/transformers/number.ts b/src/transformers/number.ts index 1bf3ddc..3d5dde2 100644 --- a/src/transformers/number.ts +++ b/src/transformers/number.ts @@ -3,6 +3,14 @@ import type { Options } from "yargs"; import { getAnyOption } from "./any"; +/** + * Transform TypeBox TNumber schema and options appended in schema to yargs + * options. + * + * @param schema TypeBox TNumber schema to transform + * @param overwrites overwrites for yargs options result + * @returns applicable yargs options in schema and overwrites + */ export function getNumberOption( schema: S, overwrites: O = {} as never, diff --git a/src/transformers/string.ts b/src/transformers/string.ts index 34ca20a..a05a05c 100644 --- a/src/transformers/string.ts +++ b/src/transformers/string.ts @@ -3,6 +3,14 @@ import type { Options } from "yargs"; import { getAnyOption } from "./any"; +/** + * Transform TypeBox TString schema and options appended in schema to yargs + * options. + * + * @param schema TypeBox TString schema to transform + * @param overwrites overwrites for yargs options result + * @returns applicable yargs options in schema and overwrites + */ export function getStringOption( schema: S, overwrites: O = {} as never, diff --git a/tests/get-options.test.ts b/tests/get-options.test.ts index 8a35269..bdf2817 100644 --- a/tests/get-options.test.ts +++ b/tests/get-options.test.ts @@ -23,6 +23,7 @@ it("should transform schemas of props in a TObject to yargs options", () => { ), order: Type.Union([Type.Literal("asc"), Type.Literal("desc")], { default: "asc", + implies: ["sort"], }), pretty: Type.Boolean({ description: "pretty print" }), }); @@ -53,6 +54,7 @@ it("should transform schemas of props in a TObject to yargs options", () => { demandOption: false, choices: ["asc", "desc"], default: "asc", + implies: ["sort"], }, pretty: { type: "boolean",