Skip to main content
Deno 2 is finally here πŸŽ‰οΈ
Learn more

Matey

Matey - ΠΌΠΎΠ΄ΡƒΠ»ΡŒ для построСния ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠΎΠ² ΠΊΠΎΠ½ΡΠΎΠ»ΡŒΠ½Ρ‹Ρ… ΠΊΠΎΠΌΠ°Π½Π΄ с субкомандами, Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°ΠΌΠΈ, опциями ΠΈ Ρ„Π»Π°Π³Π°ΠΌΠΈ.

Matey содСрТит Π΄Π²Π΅ основныС сущности: Cli ΠΈ ComandBuilder. Cli - это класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ…Ρ€Π°Π½ΠΈΡ‚ всС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ обСспСчСниС. CommandBuilder - это класс, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Π΄ΠΎΠ±Π°Π²Π»ΡΡ‚ΡŒ ΠΈΡ… Π² Cli ΠΈ Π½Π°ΡΡ‚Ρ€Π°ΠΈΠ²Π°Ρ‚ΡŒ ΠΈΡ… (ΠΎΠΏΡ†ΠΈΠΈ, Ρ„Π»Π°Π³ΠΈ, Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹, субкоманды ΠΈ Ρ‚.Π΄.).

ΠšΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹ΠΌΠΈ, Ρ‡Ρ‚ΠΎ позволяСт ΡΠΎΠ·Π΄Π°Π²Π°Ρ‚ΡŒ слоТныС ΠΊΠΎΠ½ΡΠΎΠ»ΡŒΠ½Ρ‹Π΅ прилоТСния.

ΠŸΠ»Π°Π½ΠΈΡ€ΡƒΠ΅Ρ‚ΡΡ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠ° Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ³ΠΎ Π²Π²ΠΎΠ΄Π°-Π²Ρ‹Π²ΠΎΠ΄Π°.


ОглавлСниС

ИспользованиС

Π‘Ρ…Π΅ΠΌΠ°Ρ‚ΠΈΡ‡Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€

πŸ”§ АргумСнты-ΠΎΠΏΡ†ΠΈΠΈ(ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ хранят ΠΊΠ°ΠΊΠΎΠ΅-Ρ‚ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅) ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Π΅

const argA_1: ICommandArgument = {
  name: 'argA_1',
  description: 'argA_1 description',
  type: ArgumentType.OPTION,
  valueValidator: (val: string) => val.length > 0,
  optionNameRequired: true,
  required: true,
};

🚩 АргумСнты-Ρ„Π»Π°Π³ΠΈ(Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… само ΠΏΠΎ сСбС влияСт Π½Π° Π»ΠΎΠ³ΠΈΠΊΡƒ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°) ΠΊΠ°ΠΆΠ΄ΠΎΠΉ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ΡΡ Π² Π²ΠΈΠ΄Π΅

const argA_2: ICommandArgument = {
  name: 'argA_2',
  description: 'argA_2 description',
  type: ArgumentType.FLAG,
  required: false,
};

⚑ Π‘Π°ΠΌΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π° собираСтся Ρ‚Π°ΠΊ

const cmdA = new CliCommandBuilder()
  .setName('cmdA')
  .setDescription('cmdA description')
  .addArgument(argA_1)
  .addArgument(argA_2)
  .addSubcommand(subA)
  .setHandler(handlerA)
  .build();

πŸ›‘οΈ ПослС создания ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹, Π΅Π΅ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π² Cli
ΠŸΡ€ΠΈ нСобходимости, ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ обСспСчСниС (middleware)

const cli = new Cli();
cli
  .addCommand(cmdA)
  .addCommand(cmdB)
  .addCommand(cmdC)
  .use(rexExpA, handlerA)
  .use(rexExpB, handlerB);

πŸš€ Π’Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ происходит Ρ‚Π°ΠΊ

cli.execute`cmdA --argA_1 "Hello" --argA_2 150`;

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ использования (ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠ° email)

Команда для ΠΎΡ‚ΠΏΡ€Π°Π²ΠΊΠΈ email выглядит ΠΎΠ΄Π½ΠΈΠΌ ΠΈΠ· ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ²:

  • email <email> <message>
  • email –email <email> –msg <message>

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π±ΡƒΠ΄Π΅Ρ‚ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ Π΄Π²Π° Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Π°: –email ΠΈ –msg, Π·Π°Ρ‚Π΅ΠΌ Π±ΡƒΠ΄Π΅Ρ‚ β€œΠΎΡ‚ΠΏΡ€Π°Π²Π»ΡΡ‚ΡŒβ€ сообщСниС ΠΏΠΎ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΌΡƒ адрСсу.

const emailHandler = (options: HandlerArgs) => {
  console.log(
    `Email sent to ${options['--email']} with message: ${
      options['--msg']
    }`,
  );
};

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ ΠΈ Π΅Π΅ Π°Ρ€Π³ΡƒΠΌΠ΅Π½Ρ‚Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ CommandBuilder:

import {
  ArgumentType,
  Cli,
  CliCommandBuilder,
  HandlerArgs,
  validateFunctions,
} from '../mod.ts';

const emailCommand = new CliCommandBuilder()
  .setName('email')
  .setDescription('Send an email to a specified email address')
  .addArgument({
    name: '--email',
    description: 'The email address to send the email to',
    type: ArgumentType.OPTION,
    valueValidator: validateFunctions.emailValidate,
    required: true,
  })
  .addArgument({
    name: '--msg',
    description: 'The message to include in the email',
    type: ArgumentType.OPTION,
    required: true,
  })
  .setHandler(emailHandler)
  .build();

ВмСсто validateFunctions.emailValidate ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ свою Ρ„ΡƒΠ½ΠΊΡ†ΠΈΡŽ Π²ΠΈΠ΄Π° string => boolean

ЭкзСмпляр Cli Ρ…Ρ€Π°Π½ΠΈΡ‚ всС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ ΠΈ ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΎΡ‡Π½ΠΎΠ΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ΅ обСспСчСниС. Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ Π² Cli ΠΌΠΎΠΆΠ½ΠΎ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° addCommand, Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° execute:

const cli = new Cli();
cli.addCommand(emailCommand);

await cli.execute`email example@example.com "Hello, World!"`;

Typing SVG


ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠΈ ΠΊΠΎΠΌΠΌΠΈΡ‚Π° с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ OpenAI API.

Middleware

Если ΠΏΠ΅Ρ€Π΅Π΄ срабатываниСм ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ° ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π½ΡƒΠΆΠ½ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ запрос, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ middleware-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ. Π”Π°Π½Π½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ true/false. ΠžΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊ ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ срабатываСт Π² Ρ‚ΠΎΠΌ случаС, Ссли всС middleware-Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ Π²Π΅Ρ€Π½ΡƒΠ»ΠΈ true. Если хотя Π±Ρ‹ ΠΎΠ΄Π½Π° ΠΈΠ· Π½ΠΈΡ… Π²Π΅Ρ€Π½ΡƒΠ»Π° false, Ρ†Π΅ΠΏΠΎΡ‡ΠΊΠ° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ прСрываСтся.

//middleware.ts
const helpMiddleware = {
  pattern: / help /,
  handler: (lexemes: ILexeme[]) => {
    const toHelpCmds = lexemes.filter((lexeme) => {
      return lexeme.type === LexemeType.COMMAND;
    }).map((cmd) => cmd.content);
    console.log(`Find commands ${toHelpCmds} `);
    return false;
  },
};