<!-- This file was generated by @travetto/doc and should not be modified directly -->
<!-- Please modify https://github.com/travetto/travetto/tree/main/module/app/DOC.tsx and execute "npx trv doc" to rebuild -->
# Application

## Application registration/management and run support.

**Install: @travetto/app**
```bash
npm install @travetto/app

# or

yarn add @travetto/app
```

The [Base](https://github.com/travetto/travetto/tree/main/module/base#readme "Environment config and common utilities for travetto applications.") module provides a simplistic entrypoint to allow for the application to run, but that is not sufficient for more complex applications. This module provides a decorator, [@Application](https://github.com/travetto/travetto/tree/main/module/app/src/decorator.ts#L21) who's job is to register entry points into the application, along with the associated  metadata. 

With the application, the `run` method is the entry point that will be invoked post construction of the class. Building off of the [Dependency Injection](https://github.com/travetto/travetto/tree/main/module/di#readme "Dependency registration/management and injection support."), the [@Application](https://github.com/travetto/travetto/tree/main/module/app/src/decorator.ts#L21) is a synonym for [@Injectable](https://github.com/travetto/travetto/tree/main/module/di/src/decorator.ts#L31), and inherits all the abilities of dependency injection.  This should allow for setup for any specific application that needs to be run. 

For example:

**Code: Example of Application target**
```typescript
import { Injectable, Inject } from '@travetto/di';
import { Application } from '@travetto/app';

@Injectable()
class Server {
  name = 'roger';

  async launch() {
    // ...
  }
}

@Application('simple-app')
class SimpleApp {

  @Inject()
  server: Server;

  async run() {
    return this.server.launch();
  }
}
```

Additionally, the [@Application](https://github.com/travetto/travetto/tree/main/module/app/src/decorator.ts#L21) decorator exposes some additional functionality, which can be used to launch the application.

## run() Arguments
The arguments specified in the `run` method are extracted via code transformation, and are able to be bound when invoking the application.  Whether from the command line or a plugin, the parameters will be mapped to the inputs of `run`.  For instance:

**Code: Simple Entry Point with Parameters**
```typescript
import { Application } from '@travetto/app';

@Application('simple-domain')
class SimpleApp {
  async run(domain: string, port = 3000) {
    console.log('Launching', { domain, port });
  }
}
```

## CLI - run
The run command allows for invocation of applications as defined by the [@Application](https://github.com/travetto/travetto/tree/main/module/app/src/decorator.ts#L21) decorator.  Additionally, the environment can manually be specified (dev, test, prod).

**Terminal: CLI Run Help**
```bash
$ trv run --help

Usage:  run [options] <application> [args...]

Options:
  -e, --env <env>          Application environment
  -p, --profile <profile>  Additional application profiles (default: [])
  -h, --help               display help for command

Available Applications:

   ● complex 
     usage:  complex domain:string [port:number=3000]
     target: @travetto/app:doc/complex￮Complex

     ——————————————————————————————————————————————————————————

   ● simple 
     usage:  simple domain:string [port:number=3000]
     target: @travetto/app:doc/simple￮SimpleApp

     ——————————————————————————————————————————————————————————

   ● simple-app 
     usage:  simple-app 
     target: @travetto/app:doc/entry-simple￮SimpleApp

     ——————————————————————————————————————————————————————————

   ● simple-domain 
     usage:  simple-domain domain:string [port:number=3000]
     target: @travetto/app:doc/domain￮SimpleApp

     ——————————————————————————————————————————————————————————

   ● test-ep-test 
     usage:  test-ep-test [age:number=5] [format:html|pdf=html]
     target: @travetto/app:doc/entry￮EpTest
```

Running without specifying an application `trv run`, will display all the available apps, and would look like:

**Terminal: Sample CLI Output**
```bash
$ trv run

Usage: trv run [options] <application> [args...]

Options:
  -e, --env <env>          Application environment
  -p, --profile <profile>  Additional application profiles (default: [])
  -h, --help               display help for command

Available Applications:

   ● complex 
     usage:  complex domain:string [port:number=3000]
     target: @travetto/app:doc/complex￮Complex

     ——————————————————————————————————————————————————————————

   ● simple 
     usage:  simple domain:string [port:number=3000]
     target: @travetto/app:doc/simple￮SimpleApp

     ——————————————————————————————————————————————————————————

   ● simple-app 
     usage:  simple-app 
     target: @travetto/app:doc/entry-simple￮SimpleApp

     ——————————————————————————————————————————————————————————

   ● simple-domain 
     usage:  simple-domain domain:string [port:number=3000]
     target: @travetto/app:doc/domain￮SimpleApp

     ——————————————————————————————————————————————————————————

   ● test-ep-test 
     usage:  test-ep-test [age:number=5] [format:html|pdf=html]
     target: @travetto/app:doc/entry￮EpTest
```

To invoke the `simple` application, you need to pass `domain` where port is optional with a default.

**Terminal: Invoke Simple**
```bash
$ trv run simple-domain my-domain.biz 4000

Running application { name: 'simple-domain', target: '@travetto/app:doc/domain￮SimpleApp' }
Manifest {
  info: {
    name: '@travetto-doc/app',
    main: undefined,
    author: undefined,
    license: undefined,
    version: '0.0.0',
    framework: '3.0.x'
  },
  env: {
    envName: 'dev',
    debug: '0',
    prod: false,
    test: false,
    dynamic: false,
    profiles: [ 'dev' ],
    resourcePaths: [],
    nodeVersion: 'v18.x.x'
  }
}
Config { sources: [ 'override.3 - memory://override' ], active: {} }
Launching { domain: 'my-domain.biz', port: 4000 }
```

## Type Checking
The parameters to `run` will be type checked, to ensure proper evaluation.

**Terminal: Invoke Simple with bad port**
```bash
$ trv run simple-domain my-domain.biz orange

Failed to run simple-domain, Validation errors have occurred
● port is not a valid number
```

The types are inferred from the `.run()` method parameters, but can be overridden in the [@Application](https://github.com/travetto/travetto/tree/main/module/app/src/decorator.ts#L21) annotation to support customization. Only primitive types are supported:
   *  `number` - Float or decimal
   *  `string` - Default if no type is specified
   *  `boolean` - true(yes/on/1) and false(no/off/0)
   *  `union` - Type unions of the same type (`string_a | string_b` or `1 | 2 | 3 | 4`)
Customizing the types is done by name, and allows for greater control:

**Code: Complex Entry Point with Customization**
```typescript
import { Application } from '@travetto/app';

@Application('complex')
class Complex {
  async run(domain: string, port: number = 3000) {
    console.log('Launching', { domain, port });
  }
}
```
