Coder Social home page Coder Social logo

ferdiansyah0611 / finae-x Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 0.0 174 KB

Finae-X is a command-line interface (CLI) tool that allows you to perform various tasks and operations from the command line.

License: MIT License

TypeScript 100.00%
command-line deno typescript

finae-x's Introduction

Finae-X

Finae-X is a command-line interface (CLI) tool that allows you to perform various tasks and operations from the command line. It provides a simple and intuitive way to interact with your applications and execute commands.

Installation

Add imports path to deno.json

{
	"imports": {
		"finae-x/": "https://deno.land/x/finae_x/"
	}
}

Quick Start

To quickly get started with Finae-X, you can follow the code snippet above. It demonstrates how to use the Program class to create a CLI program and define commands, arguments, and options.

import { Program } from 'finae-x/mod.ts';
import { CommandType, ProgramType } from 'finae-x/types.d.ts';

const program: ProgramType.Type = new Program('MY CLI', 'description', {
	version: '1.0.0',
});
program
	.command('main', 'description')
	.action(() => console.log('main'));
program
	.command('side', 'description')
	.argument('name', 'description')
	.action((argument: any, cmd: CommandType.Type) => console.log(argument.name));
program
	.command('section', 'description')
	.option('name', 'description')
	.action((option: any, cmd: CommandType.Type) => console.log(option.name));
program
	.command('bar', 'description')
	.argument('name', 'description')
	.option('name', 'description')
	.action((argument: any, option: any) => console.log(argument.name, option.name));
program
	.command('satset', 'description')
	.argument('name', 'description')
	.option('name', 'description')
	.action(function () {
		console.log(this.arg);
		console.log(this.opt);
	});

let result: ProgramType.ReturnExec;

result = await program.exec('main');
result = await program.exec('side ferdy');
result = await program.exec('section --name shelby');
result = await program.exec('bar dugem --name lorem');

Sample Code

Run command to view sample output

deno run -A https://deno.land/x/finae_x/example/main.ts ferdiansyah0611 10
deno run -A https://deno.land/x/finae_x/example/drink.ts
deno run -A https://deno.land/x/finae_x/example/pizza.ts
deno run -A https://deno.land/x/finae_x/example/prompt.ts

Documentation

Program

Explain the use of program:

Initialize

It imports the Program class from the specified module and creates a new instance of the program with the given name, description, and version.

import { Program } from 'finae-x/mod.ts';
import { ProgramType } from 'finae-x/types.d.ts';

const program: ProgramType.Type = new Program('MY CLI', 'description', {
	version: '1.0.0',
	// stderr: (err) => throw err,
	// suggestAfterError: true
});

Execution

It shows how to use the exec method to execute various commands, including passing arguments and options.

await program.exec('--help');
await program.exec('cmd --help');
await program.exec('cmd arg1 arg2 --opt1 data1 --opt2 data2');

Global Options

It uses the addOption method to define options with their respective descriptions. The second option also demonstrates how to specify a data type for the option using a callback function.

import { OptionType } from 'finae-x/types.d.ts';

program.addOption('--verbose', description);
program.addOption('--global', description, (cls: OptionType.Type) => cls.number());

Hook

It uses the hook method to register callback functions for events such as pre-action, post-action, pre-error, and post-error.

import { CommandType } from 'finae-x/types.d.ts';

program.hook('preAction', (_cmd: CommandType.Type | null) => {
	console.log('preAction');
});
program.hook('postAction', (_cmd: CommandType.Type | null) => {
	console.log('postAction');
});
program.hook('preError', (_cmd: CommandType.Type | null) => {
	console.log('preError');
});
program.hook('postError', (_cmd: CommandType.Type | null) => {
	console.log('postError');
});

Error

It uses the error method to display custom error messages.

program.error('Your input is invalid');

Custom Usage

It uses the usage method to specify a custom usage message, which in this case is set to 'program.test.ts'.

program.usage('program.test.ts');

Command

Explain the use of commands:

Basic

It defines a command named "side" with a description. It also defines an argument named "name" with a description. When this command is executed, the value of the "name" argument is printed to the console.

program
	.command('side', 'description')
	.argument('name', 'description')
	.action((argument: any) => console.log(argument.name));

Nested

The program has a root command named "root" with a description. It also has two sub-commands: "sub" and "world". When the "sub" command is executed, it prints "sub" to the console. Similarly, when the "world" command is executed, it prints "world" to the console. Additionally, the "down" command is a sub-command of "root" and has its own sub-command "data".

import { CommandType } from 'finae-x/types.d.ts';

const root: CommandType.Type = program.command('root', 'description');
// it will be 'root sub'
root
	.command('sub', 'description')
	.action(() => console.log('sub'));
// it will be 'root world'
root
	.command('world', 'description')
	.action(() => console.log('world'));

const down: CommandType.Type = root.command('down', 'description');
// it will be 'root down data'
down.command('data').action(() => console.log('data'));

Allow Unknown Options

The "side" command is defined with a description. By using the allowUnknownOption() method, the command allows unrecognized options to be passed. Additionally, the command defines an option named "name" with a description.

program
	.command('side', 'description')
	.allowUnknownOption()
	.option('--name', 'description');
// ...

Execution

The program has a root command named "root" with a description. When the command is executed, it prints "root" to the console. The execute() method is used to trigger the execution of the command, and it takes an object containing arguments and options as parameters. In this example, no arguments or options are passed.

const root = program
	.command('root', 'description')
	.action(() => console.log('root'));

await root.execute({
	argument: [],
	options: {},
});

Alias

Command support multiple aliases.

program
	.command('install', 'description')
	.alias('i', 'in')
	.action(() => console.log('install'));

Argument

Explain the use of argument:

Default Value

Can provide their default values.

import { ArgumentType } from 'finae-x/types.d.ts';

program
	.command('main', 'description')
	.argument('name', 'description', (cls: ArgumentType.Type) => cls.default('ferdiansyah'))
	.action(() => console.log('main'));

Type

There are several data types such as string, float, and number. String as default type.

program
	.command('main', 'description')
	.argument('str', 'description', (cls: ArgumentType.Type) => cls.string('default'))
	.argument('number', 'description', (cls: ArgumentType.Type) => cls.number(100))
	.argument('float', 'description', (cls: ArgumentType.Type) => cls.float(10.10));

Include

Supports selection based on parameter data.

program
	.command('main', 'description')
	.argument('style', 'description', (cls: ArgumentType.Type) => cls.include(['css', 'less', 'sass', 'scss']));

Exclude

Supports exceptions based on parameter data.

program
	.command('main', 'description')
	.argument('format', 'description', (cls: ArgumentType.Type) => cls.exclude(['mp3', 'mp4']));

Variadic

Supports unlimited values, making it an array.

program
	.command('main', 'description')
	.argument('name', 'description', (cls: ArgumentType.Type) => cls.variadic());

Custom Validator

Supports custom validation, must return a value.

program
	.command('main', 'description')
	.argument('name', 'description', (cls: ArgumentType.Type) =>
		cls.validator((value: string | number) => {
			if (typeof value === 'string' && value.includes('xxx')) return value.replaceAll('xxx', '[removed]');
			return value;
		}));

Option

Explain the use of options:

Default Value

Can provide their default values.

import { OptionType } from 'finae-x/types.d.ts';

program
	.command('main', 'description')
	.option('name', 'description', (cls: OptionType.Type) => cls.default('ferdiansyah'))
	.action(() => console.log('main'));

Type

There are several data types such as string, boolean, float, and number. String as default type.

program
	.command('main', 'description')
	.option('str', 'description', (cls: OptionType.Type) => cls.string('default'))
	.option('number', 'description', (cls: OptionType.Type) => cls.number(100))
	.option('float', 'description', (cls: OptionType.Type) => cls.float(10.10));
	.option('is', 'description', (cls: OptionType.Type) => cls.boolean());

Include

Supports selection based on parameter data.

program
	.command('main', 'description')
	.option('style', 'description', (cls: OptionType.Type) => cls.include(['css', 'less', 'sass', 'scss']));

Exclude

Supports exceptions based on parameter data.

program
	.command('main', 'description')
	.option('format', 'description', (cls: OptionType.Type) => cls.exclude(['mp3', 'mp4']));

Variadic

Supports unlimited values, making it an array.

program
	.command('main', 'description')
	.option('name', 'description', (cls: OptionType.Type) => cls.variadic())
	.option('number', 'description', (cls: OptionType.Type) => cls.number().variadic());

Custom Validator

Supports custom validation, must return a value.

program
	.command('main', 'description')
	.option('name', 'description', (cls) =>
		cls.validator((value: string | number) => {
			if (typeof value === 'string' && value.includes('xxx')) return value.replaceAll('xxx', '[removed]');
			return value;
		}));

Conflicts

Commands will give an error if these options run simultaneously.

program
	.command('main', 'description')
	.option('port', 'description', (cls: OptionType.Type) => cls.conflicts('default-port', 'default-config'))
	.option('default-port', 'description');
	.option('default-config', 'description');

Implies

Options will provide a default value to the specified options if the options do not have a value during execution.

program
	.command('main', 'description')
	.option('port', 'description', (cls: OptionType.Type) => cls.implies({ 'default-port': 3721 }))
	.option('default-port', 'description');

Required

Commands will give an error if the options do not have a value.

program
	.command('main', 'description')
	.option('port', 'description', (cls: OptionType.Type) => cls.required());

ENV

Options will provide a default value to the specified environment if the options do not have a value during execution.

program
	.command('main', 'description')
	.option('port', 'description', (cls: OptionType.Type) => cls.env('PORT'));

Hidden from Help

Hides options from help output.

program
	.command('main', 'description')
	.option('name', 'description', (cls: OptionType.Type) => cls.hideHelp());

Help

Explain the use of help:

Custom Help

Customize synopsis and description for help.

program.helpOption('-h, --helper', 'show help command');

Custom Section

You can add section output help with specified position: 'afterArgument' | 'afterCommand' | 'afterOption' | 'firstLine' | 'lastLine'.

const data = [
	['title', 'a'.repeat(50)],
];
program.makeSectionHelp('afterArgument', 'afterArgument:', null, data);
program.makeSectionHelp('afterCommand', 'afterCommand:', null, data);
program.makeSectionHelp('afterOption', 'afterOption:', null, data);
program.makeSectionHelp('firstLine', 'firstLine:', null, data);
program.makeSectionHelp('lastLine', 'lastLine:', null, data);

Raw text support with empty name and data.

program.makeSectionHelp(
	'afterArgument',
	null,
	null,
	[],
	`
Important!
This is raw text
`,
);

Custom Raw

You can set raw output.

program.setHelpRaw((info, command) => {
	let cmd, argument, option;
	function eachCMD(array: CommandType.Type[]) {
		return array.map((val) => {
			const detail = val.getInformation();
			return `  ${detail.name}  \t${detail.description.toUpperCase()}`;
		}).join('\n');
	}

	if (command) {
		cmd = eachCMD(command.getNested());
		argument = command.getArgument().map((val) => {
			const detail = val.getInformation();
			return `  ${detail.synopsis} (${detail.config.type})\n  ${detail.description.toUpperCase()}\n`;
		}).join('\n');
		option = command.getOption().map((val) => {
			const detail = val.getInformation();
			return `  ${detail.synopsis} (${detail.config.type})\n  ${detail.description.toUpperCase()}\n`;
		}).join('\n');
	} else {
		cmd = eachCMD(program.getAllCommands());
	}

	let text = `${info.name} v${info.version}`;
	if (cmd) {
		text += `\n\nCommand\n${cmd}`;
	}
	if (argument) {
		text += `\n\nArgument\n${argument}`;
	}
	if (option) {
		text += `\nOption\n\n${option}`;
	}
	return text;
});

Manual Show Help

Support manual to show help, pass false to argument to get output.

program.showHelp();

const output = program.showHelp(false);
console.log(output);

More Feature

Explains other features:

Suggest After Error

Activate this feature if you want to add an error message to a suggestion.

const program: ProgramType.Type = new Program('MY CLI', 'description', {
	version: '1.0.0',
	suggestAfterError: true,
});

Custom Error Message

You can change the error message with the specified key.

import { ProgramType } from 'finae-x/types.d.ts';
import message from 'finae-x/src/helpers/message.ts';
import stderr from 'finae-x/src/helpers/stderr.ts';

message.update({
	isRequired: '%s \'%s\' harus di isi',
	isNotType: '%s \'%s\' bukan sebuah type %s',
	isNotIn: '%s \'%s\' tidak termasuk dalam: %s',
	isExlude: '%s \'%s\' termasuk dalam pengecualian: %s',
	cmdNotFound: 'Command \'%s\' tidak ditemukan.',
	optionsUnknown: 'Pilihan tidak teridentifikasi \'%s\'',
	actionNotFound: 'Aksi tidak didefinisikan untuk command \'%s\'',
	mustHaveOneLength: '%s \'%s\' harus memiliki minimal punya 1 data',
	isConflictsOption: 'Pilihan \'%s\' tidak bisa digunakan dengan pilihan \'%s\'',
	suggest: 'Apakah maksud kamu \'%s\' ?',
	exceededArgument: 'Argumen telah melewati batas',
});

const program: ProgramType.Type = new Program('MY CLI', 'description', {
	version: '1.0.0',
	stderr(error) {
		if (Array.isArray(error)) {
			error = error.map((value) => value.replace('Arguments', 'Argumen').replace('Options', 'Pilihan'));
		}
		stderr(error);
	},
});

finae-x's People

Contributors

ferdiansyah0611 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.