archieve-projects/微信机器人/node_modules/cmd-ts/dist/deno_cjs/positional.ts

102 lines
2.8 KiB
TypeScript

import { ArgParser, ParsingResult, ParseContext } from './argparser.ts';
import { OutputOf } from './from.ts';
import { PositionalArgument } from './newparser/parser.ts';
import { ProvidesHelp, Descriptive, Displayed } from './helpdoc.ts';
import { Type, HasType } from './type.ts';
import * as Result from './Result.ts';
import { string } from './types.ts';
type PositionalConfig<Decoder extends Type<string, any>> = HasType<Decoder> &
Partial<Displayed & Descriptive>;
type PositionalParser<Decoder extends Type<string, any>> = ArgParser<
OutputOf<Decoder>
> &
ProvidesHelp &
Partial<Descriptive>;
function fullPositional<Decoder extends Type<string, any>>(
config: PositionalConfig<Decoder>
): PositionalParser<Decoder> {
const displayName = config.displayName ?? config.type.displayName ?? 'arg';
return {
description: config.description ?? config.type.description,
helpTopics() {
return [
{
category: 'arguments',
usage: `<${displayName}>`,
description:
config.description ?? config.type.description ?? 'self explanatory',
defaults: [],
},
];
},
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 positional = positionals[0];
if (!positional) {
return Result.err({
errors: [
{
nodes: [],
message: `No value provided for ${displayName}`,
},
],
});
}
visitedNodes.add(positional);
const decoded = await Result.safeAsync(config.type.from(positional.raw));
if (Result.isErr(decoded)) {
return Result.err({
errors: [
{
nodes: [positional],
message: decoded.error.message,
},
],
});
}
return Result.ok(decoded.value);
},
};
}
type StringType = Type<string, string>;
/**
* A positional command line argument.
*
* Decodes one argument that is not a flag or an option:
* In `hello --key value world` we have 2 positional arguments — `hello` and `world`.
*
* @param config positional argument config
*/
export function positional<Decoder extends Type<string, any>>(
config: HasType<Decoder> & Partial<Displayed & Descriptive>
): PositionalParser<Decoder>;
export function positional(
config?: Partial<HasType<never> & Displayed & Descriptive>
): PositionalParser<StringType>;
export function positional(
config?: Partial<HasType<any>> & Partial<Displayed & Descriptive>
): PositionalParser<any> {
return fullPositional({
type: string,
...config,
});
}