fontcolor_theme
Deepkit App

Argumente & Flags

Kommandoargumente im Terminal Ihres Kommandos sind einfach reguläre Argumente der execute-Methode bzw. der Funktion. Sie werden automatisch auf die Kommandozeilenargumente abgebildet. Wenn Sie einen Parameter als optional markieren, muss er nicht übergeben werden. Wenn er einen Default-Wert besitzt, muss er ebenfalls nicht übergeben werden.

Abhängig vom Typ (string, number, union, etc.) wird der übergebene Wert automatisch deserialisiert und validiert.

import { cli } from '@deepkit/app';

//funktional
new App().command('test', (name: string) => {
    console.log('Hello', name);
});

//Klasse
@cli.controller('test')
class TestCommand {
    async execute(name: string) {
        console.log('Hello', name);
    }
}

Wenn Sie dieses Kommando jetzt ausführen, ohne den Parameter name anzugeben, wird ein Fehler ausgegeben:

$ ts-node app.ts test
RequiredArgsError: Missing 1 required arg:
name

Mit --help erhalten Sie weitere Informationen über die erforderlichen Argumente:

$ ts-node app.ts test --help
USAGE
  $ ts-node-script app.ts test NAME

Sobald der Name als Argument übergeben wird, wird das Kommando ausgeführt und der Name korrekt übergeben.

$ ts-node app.ts test "beautiful world"
Hello beautiful world

Jeder primitive Parametertyp wie string, number, boolean, String-Literale, Unions davon sowie Arrays davon werden automatisch als CLI-Argumente verwendet und automatisch validiert und deserialisiert. Die Reihenfolge der Parameter bestimmt die Reihenfolge der CLI-Argumente. Sie können beliebig viele Parameter hinzufügen.

Sobald ein komplexes Objekt (Interface, Klasse, Objekt-Literal) definiert wird, wird es als Service-Abhängigkeit behandelt und der Dependency Injection Container versucht, es aufzulösen. Siehe das Kapitel Dependency Injection für weitere Informationen.

Mehrere Werte

Ein als Array typisiertes Argument nimmt alle verbleibenden Positionsargumente auf. Jeder Wert wird deserialisiert und gegen den Elementtyp validiert. Argumente nach dem Array behalten ihren Wert, sodass ein Kommando wie cp <files...> <target> wie erwartet funktioniert.

new App().command('copy', (files: string[], target: string) => {
    console.log('copy', files, 'to', target);
});

new App().command('delete', (ids: number[]) => {
    console.log('delete', ids);
});
$ ts-node app.ts copy a.txt b.txt backup/
copy [ 'a.txt', 'b.txt' ] to backup/

$ ts-node app.ts delete 1 2 3
delete [ 1, 2, 3 ]

$ ts-node app.ts delete 1 two
Invalid value for argument ids: 1,two. Cannot convert two to number [type]

Ein erforderliches Array-Argument benötigt mindestens einen Wert. Mit einem Default-Wert, z. B. ids: number[] = [], ist es optional.

Flags

Flags sind eine weitere Möglichkeit, Werte an Ihr Kommando zu übergeben. Meistens sind diese optional, müssen es aber nicht sein. Parameter, die mit dem Typ Flag dekoriert sind, können über --name value oder --name=value übergeben werden.

import { Flag } from '@deepkit/app';

//funktional
new App().command('test', (id: number & Flag) => {
    console.log('id', name);
});

//Klasse
class TestCommand {
    async execute(id: number & Flag) {
        console.log('id', id);
    }
}
$ ts-node app.ts test --help
USAGE
  $ ts-node app.ts test

OPTIONS
  --id=id  (required)

In der Hilfeansicht sehen Sie unter "OPTIONS", dass ein --id-Flag erforderlich ist. Wenn Sie dieses Flag korrekt angeben, erhält das Kommando diesen Wert.

$ ts-node app.ts test --id 23
id 23

$ ts-node app.ts test --id=23
id 23

Boolean-Flags

Flags haben den Vorteil, dass sie auch als wertloses Flag verwendet werden können, um beispielsweise ein bestimmtes Verhalten zu aktivieren. Sobald ein Parameter als optionaler Boolean markiert ist, wird dieses Verhalten aktiviert.

import { Flag } from '@deepkit/app';

//funktional
new App().command('test', (remove: boolean & Flag = false) => {
    console.log('delete?', remove);
});

//Klasse
class TestCommand {
    async execute(remove: boolean & Flag = false) {
        console.log('delete?', remove);
    }
}
$ ts-node app.ts test
delete? false

$ ts-node app.ts test --remove
delete? true

Mehrfache Flags

Um mehrere Werte an dasselbe Flag zu übergeben, kann ein Flag als Array markiert werden.

import { Flag } from '@deepkit/app';

//funktional
new App().command('test', (id: number[] & Flag = []) => {
    console.log('ids', id);
});

//Klasse
class TestCommand {
    async execute(id: number[] & Flag = []) {
        console.log('ids', id);
    }
}
$ ts-node app.ts test
ids: []

$ ts-node app.ts test --id 12
ids: [12]

$ ts-node app.ts test --id 12 --id 23
ids: [12, 23]

Einzelzeichen-Flags

Damit ein Flag auch als einzelnes Zeichen übergeben werden kann, kann Flag<{char: 'x'}> verwendet werden.

import { Flag } from '@deepkit/app';

//funktional
new App().command('test', (output: string & Flag<{char: 'o'}>) => {
    console.log('output: ', output);
});

//Klasse
class TestCommand {
    async execute(output: string & Flag<{char: 'o'}>) {
        console.log('output: ', output);
    }
}
$ ts-node app.ts test --help
USAGE
  $ ts-node app.ts test

OPTIONS
  -o, --output=output  (required)


$ ts-node app.ts test --output test.txt
output: test.txt

$ ts-node app.ts test -o test.txt
output: test.txt

Optional / Default

Die Signatur der Methode/Funktion legt fest, welche Argumente oder Flags optional sind. Wenn der Parameter im Typsystem optional ist, muss der Benutzer ihn nicht angeben.

//funktional
new App().command('test', (name?: string) => {
    console.log('Hello', name || 'nobody');
});

//Klasse
class TestCommand {
    async execute(name?: string) {
        console.log('Hello', name || 'nobody');
    }
}
$ ts-node app.ts test
Hello nobody

Dasselbe gilt für Parameter mit einem Default-Wert:

//funktional
new App().command('test', (name: string = 'body') => {
    console.log('Hello', name);
});

//Klasse
class TestCommand {
    async execute(name: string = 'body') {
        console.log('Hello', name);
    }
}
$ ts-node app.ts test
Hello nobody

Dies gilt in gleicher Weise auch für Flags.

Serialisierung / Validierung

Alle Argumente und Flags werden automatisch anhand ihrer Typen deserialisiert, validiert und können mit zusätzlichen Einschränkungen versehen werden.

So ist bei Argumenten, die als number definiert sind, im Controller immer garantiert, dass es sich um echte Zahlen handelt, obwohl das Kommandozeilen-Interface auf Text und somit auf Strings basiert.

//funktional
new App().command('test', (id: number) => {
    console.log('id', id, typeof id);
});

//Klasse
class TestCommand {
    async execute(id: number) {
        console.log('id', id, typeof id);
    }
}
$ ts-node app.ts test 123
id 123 number

Zusätzliche Einschränkungen können mit den Typannotationen aus @deepkit/type definiert werden.

import { Positive } from '@deepkit/type';
//funktional
new App().command('test', (id: number & Positive) => {
    console.log('id', id, typeof id);
});

//Klasse
class TestCommand {
    async execute(id: number & Positive) {
        console.log('id', id, typeof id);
    }
}

Der Typ Postive bei id gibt an, dass nur positive Zahlen erlaubt sind. Übergibt der Benutzer nun eine negative Zahl, wird der Code gar nicht erst ausgeführt und eine Fehlermeldung angezeigt.

$ ts-node app.ts test -123
Validation error in id: Number needs to be positive [positive]

Diese zusätzliche Validierung, die sehr einfach umzusetzen ist, macht das Kommando deutlich robuster gegenüber fehlerhaften Eingaben. Siehe das Kapitel Validierung für weitere Informationen.

Beschreibung

Um ein Flag oder Argument zu beschreiben, verwenden Sie den Kommentar-Decorator @description.

import { Positive } from '@deepkit/type';

class TestCommand {
    async execute(
        /** @description The users identifier */
        id: number & Positive,
        /** @description Delete the user? */
        remove: boolean = false
    ) {
        console.log('id', id, typeof id);
    }
}

In der Hilfeansicht erscheint diese Beschreibung nach dem Flag bzw. Argument:

$ ts-node app.ts test --help
USAGE
  $ ts-node app.ts test ID

ARGUMENTS
  ID  The users identifier

OPTIONS
  --remove  Delete the user?
English中文 (Chinese)한국어 (Korean)日本語 (Japanese)Deutsch (German)