Development of console applications.
main.js
/ main.ts
import { Scheduler, Flag } from 'task-scheduling'
import { ShowInfoCommand } from './commands/show-info-command'
// global flag (all commands)
Scheduler.registerFlag(new Flag('help', { alias: 'h', type: 'boolean', default: false }))
// add a command
Scheduler.registerCommand(new ShowInfoCommand())
// run / execute by a string
Scheduler.execute(['not-exists', '--help'])
Scheduler.execute(['show-info', '--data=22']) // or "node main.js show-info --data=22"
Scheduler.execute(['show-info', '--data', '22']) // or "node main.js show-info --data 22"
// run / execute by process argv
Scheduler.executeByProcess()
commands/show-info-command.js
/ commands/show-info-command.ts
import { BaseCommand, Flag, Flags } from 'task-scheduling'
export class ShowInfoCommand extends BaseCommand {
name: string = 'show-info'
description: string = 'Show a message'
flags: Flag[] = [
new Flag('data', { alias: 'd', type: 'number', default: 2 })
]
async run(@Flags() flags: Flags, @Flags('data') data: number) {
console.log('What did you expect? A number? Take this:', data*2)
}
}
// NPM
npm i task-scheduling --save
// Yarn
yarn add task-scheduling
The preferred way to create a command is through the BaseCommand
class.
import { Scheduler, BaseCommand } from 'task-scheduling'
export class MyFirstCommand extends BaseCommand {
name = 'callme'
description = 'Description of the command that will appear in the help message.'
async run() {
console.log('Thanks for invoking me.')
}
}
Scheduler.registerCommand(new MyFirstCommand())
Another way to create commands is inline. This option does not need to register the command with the "registerCommand" method.
import { task } from 'task-scheduling'
task('callme', 'Description of the command that will appear in the help message.', [], async () => {
console.log('Thanks for invoking me.')
})
// "task" is an alias of "Scheduler.registerSimpleCommand"
There are times when we need to execute a task even when a command is not received. For these cases we can register a "no name" command.
import { Scheduler, BaseCommand, task } from 'task-scheduling'
export class NoNameCommand extends BaseCommand {
// without name and description
/*name = ''
description = ''*/
async run() {
console.log('Use --help')
}
}
Scheduler.registerCommand(new NoNameCommand())
// Or inline
task(undefined, undefined, [], async () => {
console.log('Use --help')
})
If you try to execute a command not registered in the system, the "default" command will be executed.
import { Scheduler, BaseCommand } from 'task-scheduling'
export class Default404Command extends BaseCommand {
async run() {
console.log('The command you are trying to execute is not valid. Use --help.')
}
}
Scheduler.registerDefault(new Default404Command())
// Or inline
Scheduler.registerSimpleDefault(async () => {
console.log('The command you are trying to execute is not valid. Use --help.')
})
The reading of the values of the flags accepts the formats:
example-command --name value1
example-command -n value1
example-command --name=value1
example-command -n=value1
example-command --files file1.js file2.js file3.js // for array type
example-command -f file1.js file2.js file3.js // for array type
The way to create a flag instance is with the Flag
class.
Note: It is not advisable to create the flags in files separated from the commands, this is just an example where they are separated so that the procedure is better understood.
flags/complete-name-flag.js
/ flags/complete-name-flag.ts
import { Flag } from 'task-scheduling'
export const CompleteNameFlag = new Flag('complete-name', {
description: 'to show in help',
alias: 'c', // To use as: "command-name --flag-one value1 -c value2"
type: 'string',
default: 'Horus from the ground fuck',
})
commands/say-hello-command.js
/ commands/say-hello-command.ts
import { BaseCommand } from 'task-scheduling'
import { CompleteNameFlag } from './../flags/complete-name-flag'
export class SayHelloCommand extends BaseCommand {
name = 'say-hello'
description = 'Send me a simple greeting!'
flags = [CompleteNameFlag]
}
Recommended format:
commands/say-hello-command.js
/ commands/say-hello-command.ts
import { BaseCommand, Flag } from 'task-scheduling'
export class SayHelloCommand extends BaseCommand {
name = 'say-hello'
description = 'Send me a simple greeting!'
flags = [
new Flag('complete-name', { description: 'to show in help', alias: 'c', type: 'string', default: 'Horus' })
]
}
The available types of data for the flags are (Valid uses):
new Flag('name', { type: 'string', default: 'MyNameIs (that\'s my name)' })
example-command --name=Biig
example-command --name "Biig Piig"
example-command --name= // This will return an empty string ('')
new Flag('help', { alias: 'h', type: 'boolean', default: false })
example-command --help // true
example-command -h // true
example-command --help=true
example-command --help=1
example-command --help=false
example-command --help=0
new Flag('add', { type: 'number', default: 4 })
example-command // 4
example-command --add // 0
example-command --add=9
example-command --add 44
new Flag('json', { type: 'object', default: { data: null, of: null, obj: null } })
example-command --json="{ data: 'to show', show: 'to data' }"
example-command --json "{ data: 'to show', show: 'to data' }"
new Flag('files', { type: 'array', default: ['file1.js'] })
example-command --files file1.js file2.js file3.js file4.js
The array type has the peculiarity of a data subtype. This is because it is necessary to know to what type of data corresponds the information that is expected to be received.
new Flag('files', { type: 'array', subtype: 'string', default: ['index.js'] })
new Flag('answers', { type: 'array', subtype: 'boolean', default: [true, false, true, true] })
new Flag('sum', { type: 'array', subtype: 'number', default: [0] })
// ...
Once we have done the command and it is executed, we need to know what value was established for the flag. For this we occupy the decorator @Flags:
import { BaseCommand, Flags, Flag, Scheduler } from 'task-scheduling'
export class NoNameCommand extends BaseCommand {
flags = [
new Flag('--help', { alias: 'h', type: 'boolean', default: false, description: 'Show help message.' })
]
async run(@Flags() flags: Flags, @Flags('help') help: boolean) {
if(help) { // or "flags.help.value"
console.log(Scheduler.help())
}
else {
console.log('Use --help')
}
}
}
On inline commands it's a bit different (and Javascript). Since decorators are not supported in anonymous functions, the only way to obtain the flags is:
import { BaseCommand, Flag, Scheduler, task } from 'task-scheduling'
task(
undefined,
undefined,
[ new Flag('--help', { alias: 'h', type: 'boolean', default: false, description: 'Show help message.' }) ],
async ({ flags }) => {
if(flags.help.value) {
console.log(Scheduler.help())
}
else {
console.log('Use --help')
}
})
The system displays help and error messages automatically in certain cases.
CommandNotFoundError
- When a command does not exist, a message is displayed with the list of available commands and their respective flags, in addition to the global flags.
FlagNotFoundError
- When trying to occupy an unregistered flag. If it is used with a command then it will show the list of available flags for that command. If used without a specific command then it will display the same message as with
CommandNotFoundError
.
- When trying to occupy an unregistered flag. If it is used with a command then it will show the list of available flags for that command. If used without a specific command then it will display the same message as with
InvalidFlagValueError
- If an erroneous value is sent in a flag, an error message will be displayed warning that X data type was expected. For example, if a string is sent in a number flag, it will display the message.
It is possible to get the help message (in string format) with the Scheduler.help()
method. Then it is printed with console.log
or another.
I got bored writing the documentation. If I remember later, I will write this part. If you want to see the options of the methods you can use the autocomplete of Typescript (and its IDEs / code editors).
Some main methods have an alias for faster, intuitive and clean code use.
import { task, Flag } from 'task-scheduling'
const command_flags = [new Flag('data', { alias: 'd', type: 'number', default: 2 })]
//Scheduler.registerSimpleCommand
task('show-info', 'without description', command_flags, async ({ flags }) => {
const data = flags.data.value
console.log('What did you expect? A number? Take this:', data*2)
})