python-archieve-projects/WechatBot/node_modules/cmd-ts/dist/deno_cjs/restPositionals.ts

107 lines
3.0 KiB
TypeScript

import {
ArgParser,
ParsingResult,
ParseContext,
ParsingError,
} from './argparser.ts';
import { OutputOf } from './from.ts';
import { PositionalArgument } from './newparser/parser.ts';
import { Type, HasType } from './type.ts';
import { ProvidesHelp, Displayed, Descriptive } from './helpdoc.ts';
import * as Result from './Result.ts';
import { string } from './types.ts';
type RestPositionalsConfig<Decoder extends Type<string, any>> = HasType<
Decoder
> &
Partial<Displayed & Descriptive>;
/**
* Read all the positionals and decode them using the type provided.
* Works best when it is the last item on the `command` construct, to be
* used like the `...rest` operator in JS and TypeScript.
*/
function fullRestPositionals<Decoder extends Type<string, any>>(
config: RestPositionalsConfig<Decoder>
): ArgParser<OutputOf<Decoder>[]> & ProvidesHelp {
return {
helpTopics() {
const displayName =
config.displayName ?? config.type.displayName ?? 'arg';
return [
{
usage: `[...${displayName}]`,
category: 'arguments',
defaults: [],
description: config.description ?? config.type.description ?? '',
},
];
},
register(_opts) {},
async parse({
nodes,
visitedNodes,
}: ParseContext): Promise<ParsingResult<OutputOf<Decoder>[]>> {
const positionals = nodes.filter(
(node): node is PositionalArgument =>
node.type === 'positionalArgument' && !visitedNodes.has(node)
);
const results: OutputOf<Decoder>[] = [];
let errors: ParsingError[] = [];
for (const positional of positionals) {
visitedNodes.add(positional);
const decoded = await Result.safeAsync(
config.type.from(positional.raw)
);
if (Result.isOk(decoded)) {
results.push(decoded.value);
} else {
errors.push({
nodes: [positional],
message: decoded.error.message,
});
}
}
if (errors.length > 0) {
return Result.err({
errors,
});
}
return Result.ok(results);
},
};
}
type StringType = Type<string, string>;
type RestPositionalsParser<Decoder extends Type<string, any>> = ArgParser<
OutputOf<Decoder>[]
> &
ProvidesHelp;
/**
* Read all the positionals and decode them using the type provided.
* Works best when it is the last item on the `command` construct, to be
* used like the `...rest` operator in JS and TypeScript.
*
* @param config rest positionals argument config
*/
export function restPositionals<Decoder extends Type<string, any>>(
config: HasType<Decoder> & Partial<Displayed & Descriptive>
): RestPositionalsParser<Decoder>;
export function restPositionals(
config?: Partial<HasType<never> & Displayed & Descriptive>
): RestPositionalsParser<StringType>;
export function restPositionals(
config?: Partial<HasType<any>> & Partial<Displayed & Descriptive>
): RestPositionalsParser<any> {
return fullRestPositionals({
type: string,
...config,
});
}