# Deepkit

> Deepkit is a TypeScript framework with runtime types: its type compiler makes TypeScript types available at runtime, so one type is used for validation, serialization, the database (ORM), HTTP, RPC and dependency injection, without schemas, decorators for dependency injection or code generation.

The complete documentation in one file: [llms-full.txt](https://deepkit.io/llms-full.txt)

Important for writing Deepkit code:

- Runtime types need the type compiler in the build: `"reflection": true` in tsconfig.json, and `npx deepkit-type-install` to install it into TypeScript (or the Vite and Bun plugins). Without it, types are not available at runtime.
- Validation and database options are intersections with the type: `string & MinLength<3>`, `number & PrimaryKey & AutoIncrement`, `string & Email`.
- Dependency injection resolves constructor parameters by their type, interfaces included. No decorators are needed for it.
- HTTP routes and CLI commands take their parameters from the function signature: `HttpBody<T>`, `HttpQuery<T>`, `Flag`.
- A new project: `npm init @deepkit/app@latest my-app`.

Every documentation page is available as markdown by adding `.md` to its URL, package pages include their API reference.

---

Source: https://deepkit.io/en/documentation

# Documentation

Deepkit is an open-source TypeScript framework for backend applications freely available under the MIT license, designed to help you build scalable and maintainable backend applications. It's designed to work in the browser and Node.js, but can run in any proper JavaScript environment.

Here you find chapters for the different components of Deepkit and API references for all our packages.

If you need help, please feel free to join our [Discord server](https://discord.com/invite/PtfVf7B8UU) or open an issue 
on [GitHub](https://github.com/deepkit/deepkit-framework).

## Chapters


- [App](https://deepkit.io/en/documentation/app.md) - Write your first application with Deepkit based on the command line interface.
- [Framework](https://deepkit.io/en/documentation/framework.md) - Add application (HTTP/RPC) server, API docs, debugger, integration tests, and more to your application.
- [Runtime Types](https://deepkit.io/en/documentation/runtime-types.md) - Learn about TypeScript runtime types, and to validate and transform data.
- [Dependency Injection](https://deepkit.io/en/documentation/dependency-injection.md) - Dependency injection container, inversion of control, and dependency inversion.
- [Filesystem](https://deepkit.io/en/documentation/filesystem.md) - Filesystem abstraction to work with local and remote files systems in unified way.
- [Broker](https://deepkit.io/en/documentation/broker.md) - Message broker abstraction to work with distributed L2 cache, pub/sub, queues, central atomic locks, or key-value store.
- [HTTP](https://deepkit.io/en/documentation/http.md) - HTTP server abstraction to build type-safe endpoints.
- [RPC](https://deepkit.io/en/documentation/rpc.md) - Remote procedure call abstraction to connect frontend with backend, or to connect multiple backend services.
- [ORM](https://deepkit.io/en/documentation/orm.md) - ORM and DBAL to store and query data in a type-safe way.
- [Desktop-UI](https://deepkit.io/en/documentation/desktop-ui/getting-started) - Build GUI applications with Deepkit's Angular-based UI framework.

## API Reference

Following is a complete list of all Deepkit packages with links to their API documentation.

### Composition

- [@deepkit/app](https://deepkit.io/en/documentation/package/app.md)
- [@deepkit/framework](https://deepkit.io/en/documentation/package/framework.md)
- [@deepkit/http](https://deepkit.io/en/documentation/package/http.md)
- [@deepkit/angular-ssr](https://deepkit.io/en/documentation/package/angular-ssr.md)

### Infrastructure

- [@deepkit/rpc](https://deepkit.io/en/documentation/package/rpc.md)
- [@deepkit/rpc-tcp](https://deepkit.io/en/documentation/package/rpc-tcp.md)
- [@deepkit/broker](https://deepkit.io/en/documentation/package/broker.md)
- [@deepkit/broker-redis](https://deepkit.io/en/documentation/package/broker-redis.md)

### Filesystem

- [@deepkit/filesystem](https://deepkit.io/en/documentation/package/filesystem.md)
- [@deepkit/filesystem-ftp](https://deepkit.io/en/documentation/package/filesystem-ftp.md)
- [@deepkit/filesystem-sftp](https://deepkit.io/en/documentation/package/filesystem-sftp.md)
- [@deepkit/filesystem-s3](https://deepkit.io/en/documentation/package/filesystem-aws-s3.md)
- [@deepkit/filesystem-google](https://deepkit.io/en/documentation/package/filesystem-google.md)
- [@deepkit/filesystem-database](https://deepkit.io/en/documentation/package/filesystem-database.md)

### Database

- [@deepkit/orm](https://deepkit.io/en/documentation/package/orm.md)
- [@deepkit/mysql](https://deepkit.io/en/documentation/package/mysql.md)
- [@deepkit/postgres](https://deepkit.io/en/documentation/package/postgres.md)
- [@deepkit/sqlite](https://deepkit.io/en/documentation/package/sqlite.md)
- [@deepkit/mongodb](https://deepkit.io/en/documentation/package/mongo.md)

### Fundamentals

- [@deepkit/type](https://deepkit.io/en/documentation/package/type.md)
- [@deepkit/event](https://deepkit.io/en/documentation/package/event.md)
- [@deepkit/injector](https://deepkit.io/en/documentation/package/injector.md)
- [@deepkit/template](https://deepkit.io/en/documentation/package/template.md)
- [@deepkit/logger](https://deepkit.io/en/documentation/package/logger.md)
- [@deepkit/workflow](https://deepkit.io/en/documentation/package/workflow.md)
- [@deepkit/stopwatch](https://deepkit.io/en/documentation/package/stopwatch.md)

### Tools

- [@deepkit/api-console](https://deepkit.io/en/documentation/package/api-console.md)
- [@deepkit/devtool](https://deepkit.io/en/documentation/package/devtool.md)
- [@deepkit/desktop-ui](https://deepkit.io/en/documentation/desktop-ui/getting-started)
- [@deepkit/orm-browser](https://deepkit.io/en/documentation/package/orm-browser.md)
- [@deepkit/bench](https://deepkit.io/en/documentation/package/bench.md)
- [@deepkit/run](https://deepkit.io/en/documentation/package/run.md)

### Core

- [@deepkit/bson](https://deepkit.io/en/documentation/package/bson.md)
- [@deepkit/core](https://deepkit.io/en/documentation/package/core.md)
- [@deepkit/topsort](https://deepkit.io/en/documentation/package/topsort.md)

### Runtime

- [@deepkit/vite](https://deepkit.io/en/documentation/package/vite.md)
- [@deepkit/bun](https://deepkit.io/en/documentation/package/bun.md)
- [@deepkit/type-compiler](https://deepkit.io/en/documentation/package/type-compiler.md)

---

Source: https://deepkit.io/en/documentation/introduction

# Introduction

TypeScript has emerged as a highly scalable superset of JavaScript, engineered for the development of more secure and robust applications. While JavaScript has amassed a considerable developer community and ecosystem, TypeScript brings the power of static typing to JavaScript, substantially reducing runtime errors and making codebases easier to maintain and understand. However, despite its advantages, TypeScript's potential has not been fully exploited, especially when it comes to implementing complex enterprise-level solutions. TypeScript inherently eliminates its type information at compile time, leaving a crucial gap in runtime functionality and making it necessary to implement all sorts of unergonomic workarounds to retain type information. Be it code generation, limiting decorators, or custom type builders with complex inferring step like Zod, all of these solutions are cumbersome, slow, and error-prone. This results in not only slower development speed but also less robust applications, especially in large teams and complex projects.

Enter Deepkit, a framework that revolutionizes how TypeScript can be employed to construct intricate and efficient software solutions. Designed in TypeScript and for TypeScript, Deepkit not only enables type safety during development but extends the benefits of TypeScript's type system to runtime. By retaining type information at runtime, Deepkit opens the door to a plethora of new functionalities, including dynamic type computation, data validation, and serialization, that were previously cumbersome to implement.

While Deepkit is engineered to cater to high-complexity projects and enterprise-level applications, its agility and modular architecture make it equally suitable for smaller applications. Its extensive libraries cover common use-cases and can be used either individually or collectively, based on the project's needs. Deepkit aims to be as flexible as necessary and as structured as required, allowing developers to maintain high development speeds, both in the short term and the long term.

## Why Deepkit?

The TypeScript ecosystem is abundant with libraries and tools, offering solutions for almost every conceivable problem. While this plethora of choices is empowering, it often results in complexity due to mismatched philosophies, APIs, and code qualities between different libraries. Integrating these disparate components requires additional abstractions and often results in lots of glue code which can become a maintenance nightmare and gets out of hand fairly quickly reducing development speed drastically. Deepkit aims to alleviate these challenges by providing a unified framework, bringing together core functionalities that virtually every project needs. Its harmonized set of libraries and components are designed to work seamlessly together, thus bridging the gaps that exist in the fragmented TypeScript ecosystem.

### Proven Enterprise Principles

Deepkit draws inspiration from well-established enterprise frameworks like Java's Spring and PHP's Laravel and Symfony. These frameworks have proven their efficiency and robustness over decades, being the backbone of countless successful projects. Deepkit brings similar enterprise design patterns and concepts to the TypeScript world in a new and unique way, allowing developers to benefit from years of collective wisdom.

These patterns offer not only a proven way to structure applications but also facilitate development, especially in large teams. By leveraging these tried-and-true methodologies, Deepkit aims to provide a level of reliability and scalability that has been elusive in the TypeScript landscape.

### Agile / Long-term Performance

Deepkit is engineered with agility in mind, offering tools and features that accelerate initial development and provide long-term maintenance benefits. Unlike some frameworks that prioritize initial speed at the expense of future scalability, Deepkit balances both. Its design patterns are easy to grasp, making it simple to get started. However, they also scale effectively, ensuring that even as the project and team grow, development speed doesn't diminish. 

This forward-thinking approach makes Deepkit not just an ideal choice for quick MVPs but also for complex, long-lived enterprise applications.

### Developer Experience

Finally, Deepkit places a strong emphasis on developer experience. The framework offers intuitive APIs, detailed documentation, and a supportive community, all aimed at helping developers focus on solving business problems rather than wrestling with technical complexities. Whether you are building a small application or a large enterprise-grade system, Deepkit provides the tools and practices to make your development journey smooth and rewarding.

## Key Features

### Runtime Types

One of Deepkit's standout features is its ability to retain type information at runtime. Traditional TypeScript frameworks often discard this crucial data during the compilation process, making runtime operations like data validation, serialization, or dependency injection much more cumbersome. Deepkit's type compiler uniquely enables dynamic type computation and reading of existing type information at runtime. This not only offers greater flexibility but also results in more robust and typesafe applications, streamlining the development of complex systems.


### Comprehensive Library Suite

Deepkit provides a complete ecosystem of libraries designed to accelerate various facets of application development. From database abstraction and CLI parsers to HTTP routers and RPC frameworks, Deepkit's libraries offer a unified solution to meet diverse programming needs. All of these libraries come with the added advantage of leveraging TypeScript’s type system at runtime, which significantly reduces boilerplate and increases code clarity. The modularity of Deepkit allows developers to either use individual libraries for specific tasks or employ the entire framework to build full-fledged, production-ready applications.

## High-Performance & Scalability

Maintaining development speed as projects grow in complexity is a formidable challenge. Deepkit addresses this issue head-on with its emphasis on applying proven enterprise design patterns that scale well with larger teams and more complex codebases. The framework incorporates established enterprise design patterns that have proven to scale well with larger teams and more complex codebases. Deepkit’s approach ensures that projects remain agile and efficient, not just in the initial stages but throughout their lifecycle. This is achieved by minimizing boilerplate and leveraging design patterns in the most ergonomic way possible, allowing teams to maintain high productivity levels over the long term.



### Isomorphic TypeScript

Deepkit is designed to maximize the benefits of Isomorphic TypeScript, which allows the same codebase to be used across multiple platforms—be it frontend, backend, or even mobile applications. This results in significant time and cost savings as code can be shared among various departments, simplifying recruitment and facilitating easier knowledge transfer within teams. Deepkit fully harnesses the power of Isomorphic TypeScript, providing an integrated, cross-platform development experience that significantly outpaces traditional dual-stack approaches.

---

Source: https://deepkit.io/en/documentation/app

# Deepkit App

The Deepkit App abstraction is the most fundamental building block of a Deepkit application. It is usually where you start building your application if you are not using the
libraries standalone.
It is a regular TypeScript file that you execute with a runtime like Node.js. It is the entry point for your application and provides a way to define CLI commands, services,
configuration, events, and more.

Command-line Interface (CLI) programs are programs that interact via the terminal in the form of text input and text output. The advantage of interacting with the application in
this variant is that only a terminal must exist either locally or via an SSH connection.

It provides:

- CLI commands
- Module system
- Service container
- Dependency injection
- Event system
- Logger
- Configuration loader (env, dotenv, json)

A command in Deepkit has full access to the DI container and can thus access all providers and configuration options. The arguments and options of the CLI commands are controlled
by parameters declaration via TypeScript types and are automatically serialized and validated.

[Deepkit Framework](https://deepkit.io/en/documentation/framework.md) with `@deepkit/framework` extends this further with an application server for HTTP/RPC, a debugger/profiler, and much more.

Example:

```typescript
import { App, Flag } from '@deepkit/app';
import { Database } from './database';

const app = new App({
    providers: [Database]
});

async function testCommand(
    name: string, // CLI argument
    age: number & Flag, // CLI flag
    database: Database, // Dependency Injection
) {
    console.log(`Hello ${name}!`);
    const users = await database.query<User>().find();
}

app.command('test', testCommand);

void app.run();
```

```sh
ts-node app.ts test John --age 42
```

## Installation Easy

The easiest way to get started is to use NPM init to create a new Deepkit project.

```shell
npm init @deepkit/app@latest my-deepkit-app
````

This will create a new folder `my-deepkit-app` with all the dependencies and a basic `app.ts` file.

```sh
cd my-deepkit-app
npm run app
````

This will run the `app.ts` file with `ts-node` and show you the available commands. You can start from here and add your own commands, controllers, and so on.

## Installation Manually

Deepkit App is based on [Deepkit Runtime Types](https://deepkit.io/en/documentation/runtime-types.md), so let's install all dependencies:

```bash
mkdir my-project && cd my-project

npm install typescript ts-node 
npm install @deepkit/app @deepkit/type @deepkit/type-compiler
```

Next, we make sure Deepkit's type compiler is installed into the installed TypeScript package at `node_modules/typescript` by running the following command:

```sh
./node_modules/.bin/deepkit-type-install
```

Make sure that all peer dependencies are installed. By default, NPM 7+ installs them automatically.

To compile your application, we need the TypeScript compiler and recommend `ts-node` to easily run the app.

An alternative to using `ts-node` is to compile the source code with the TypeScript compiler and execute the JavaScript source code directly. This has the advantage of dramatically
increasing execution speed for short commands. However, it also creates additional workflow overhead by either manually running the compiler or setting up a watcher. For this
reason, `ts-node` is used in all examples in this documentation.

## First application

Since the Deepkit framework does not use configuration files or a special folder structure, you can structure your project however you want. The only two files you need to get
started are the TypeScript app.ts file and the TypeScript configuration tsconfig.json.

Our goal is to have the following files in our project folder:

```
.
├── app.ts
├── node_modules
├── package-lock.json
└── tsconfig.json
```

We set up a basic tsconfig file and enable Deepkit's type compiler by setting `reflection` to `true`.
This is required to use the dependency injection container and other features.

```json title=tsconfig.json
{
  "compilerOptions": {
    "outDir": "./dist",
    "experimentalDecorators": true,
    "strict": true,
    "esModuleInterop": true,
    "target": "es2020",
    "module": "CommonJS",
    "moduleResolution": "node"
  },
  "reflection": true,
  "files": [
    "app.ts"
  ]
}
```

```typescript title=app.ts
import { App } from '@deepkit/app';
import { Logger } from '@deepkit/logger';

const app = new App();

app.command('test', (logger: Logger) => {
    logger.log('Hello World!');
});

app.run();
```

In this code, you can see that we have defined a test command and created a new app that we run directly using `run()`. By running this script, we start the app.

and then run it directly.

```sh
$ ./node_modules/.bin/ts-node app.ts
VERSION
  Node

USAGE
  $ ts-node app.ts [COMMAND]

COMMANDS
  test
```

Now, to execute our test command, we run the following command.

```sh
$ ./node_modules/.bin/ts-node app.ts test
Hello World
```

In Deepkit everything is now done via this `app.ts`. You can rename the file as you like or create more. Custom CLI commands, HTTP/RPC server, migration commands, and so on are all
started from this entry point.

## Arguments & Flags

Deepkit App automatically converts function parameters into CLI arguments and flags. The order of the parameters dictates the order of the CLI arguments

Parameters can be any TypeScript type and are automatically validated and deserialized.

See the chapter [Arguments & Flags](https://deepkit.io/en/documentation/app/arguments.md) for more information.

## Dependency Injection

Deepkit App sets up a service container and for each imported module its own Dependency Injection container that inherits from its parents.
It brings out of the box following providers you can automatically inject into your services, controllers, and event listeners:

- `Logger` for logging
- `EventDispatcher` for event handling
- `CliControllerRegistry` for registered CLI commands
- `MiddlewareRegistry` for registered middleware
- `InjectorContext` for the current injector context

As soon as you import Deepkit Framework you get additional providers. See [Deepkit Framework](https://deepkit.io/en/documentation/framework.md) for more details.

## Exit code

The exit code is 0 by default, which means that the command was executed successfully. To change the exit code, a number other than 0 should be returned in the execute method or command callback.

```typescript

@cli.controller('test')
export class TestCommand {
    async execute() {
        console.error('Error :(');
        return 12;
    }
}
```

---

Source: https://deepkit.io/en/documentation/app/arguments

# Arguments & Flags

Command arguments in the terminal of your command are just regular arguments of the `execute` method or the function. They are automatically mapped to the command line arguments.
If you mark a parameter optional, it is not required to be passed. If you have a default value, it is also not required to be passed.

Depending on the type (string, number, union, etc) the passed value is automatically deserialized and validated.

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

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

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

If you execute this command now without specifying the name parameter, an error will be issued:

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

By using `--help` you will get more information about the required arguments:

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

Once the name is passed as an argument, the command is executed and the name is passed correctly.

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

Every primitive parameter type like string, number, boolean, string literals, union of them, as well as arrays of them, are automatically used as CLI arguments
and are automatically validated and deserialized. The order of the parameters dictates the order of the CLI arguments. You can add as many parameters as you want.

As soon as a complex object (interface, class, object literal) is defined, it is treated as a service dependency
and the Dependency Injection Container tries to resolve it. See the chapter [Dependency Injection](https://deepkit.io/en/documentation/app/dependency-injection.md) for more information.

### Multiple Values

An argument typed as array takes all remaining positional arguments. Each value is deserialized and validated against the element type.
Arguments after the array keep their value, so a command like `cp <files...> <target>` works as expected.

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

new App().command('delete', (ids: number[]) => {
    console.log('delete', ids);
});
```

```sh
$ 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]
```

A required array argument needs at least one value. With a default value, e.g. `ids: number[] = []`, it is optional.

## Flags

Flags are another way to pass values to your command. Mostly these are optional, but they don't have to be. Parameters decorated with the `Flag` type can be passed via `--name value` or `--name=value`.

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

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

//class
class TestCommand {
    async execute(id: number & Flag) {
        console.log('id', id);
    }
}
```

```sh
$ ts-node app.ts test --help
USAGE
  $ ts-node app.ts test

OPTIONS
  --id=id  (required)
```

In the help view you can see in the "OPTIONS" that a `--id` flag is necessary. If you enter this flag correctly, the command will receive this value.

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

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

### Boolean Flags

Flags have the advantage that they can also be used as a valueless flag, for example to activate a certain behavior. As soon as a parameter is marked as an optional Boolean, this behavior is activated.

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

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

//class
class TestCommand {
    async execute(remove: boolean & Flag = false) {
        console.log('delete?', remove);
    }
}
```

```sh
$ ts-node app.ts test
delete? false

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

### Multiple Flags

To pass multiple values to the same flag, a flag can be marked as an array.

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

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

//class
class TestCommand {
    async execute(id: number[] & Flag = []) {
        console.log('ids', id);
    }
}
```

```sh
$ 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]
```

### Single Character Flags

To allow a flag to be passed as a single character as well, `Flag<{char: 'x'}>` can be used.

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

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

//class
class TestCommand {
    async execute(output: string & Flag<{char: 'o'}>) {
        console.log('output: ', output);
    }
}
```

```sh
$ 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

The signature of the method/function defines which arguments or flags are optional. If the parameter is optional in the type system, the user does not have to provide it.

```typescript

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

//class
class TestCommand {
    async execute(name?: string) {
        console.log('Hello', name || 'nobody');
    }
}
```

```sh
$ ts-node app.ts test
Hello nobody
```

The same for parameters with a default value:

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

//class
class TestCommand {
    async execute(name: string = 'body') {
        console.log('Hello', name);
    }
}
```

```sh
$ ts-node app.ts test
Hello nobody
```

This also applies to flags in the same way.


## Serialization / Validation

All arguments and flags are automatically deserialized based on its types, validated and can be provided with additional constraints.

Thus, arguments defined as numbers are always guaranteed to be real numbers in the controller, even though the command-line interface is based on text and thus strings. 

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

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

```sh
$ ts-node app.ts test 123
id 123 number
```

Additional constraints can be defined with the type annotations from `@deepkit/type`.

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

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

The type `Postive` in `id` indicates that only positive numbers are allowed. If the user now passes a negative number, the code will not be executed at all and an error message will be presented.

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

This additional validation, which is very easy to do, makes the command much more robust against wrong entries. See the chapter [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md) for more information.

## Description

To describe a flag or argument, use `@description` comment decorator.

```typescript
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 the help view, this description appears after the flag or argument:

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

ARGUMENTS
  ID  The users identifier

OPTIONS
  --remove  Delete the user?
```

---

Source: https://deepkit.io/en/documentation/app/dependency-injection

# Dependency Injection

All commands have full access to the Dependency Injection Container. You can define dependencies in the constructor of your
command or controller and the Dependency Injection Container tries to resolve it. 

See the chapter [Dependency Injection](https://deepkit.io/en/documentation/dependency-injection.md) for more information.

```typescript
import { App, cli } from '@deepkit/app';
import { Logger, ConsoleTransport } from '@deepkit/logger';

new App({
    providers: [{provide: Logger, useValue: new Logger([new ConsoleTransport])}],
}).command('test', (logger: Logger) => {
    logger.log('Hello World!');
});
```

```typescript
@cli.controller('test', {
    description: 'My super first command'
})
class TestCommand {
    constructor(protected logger: Logger) {
    }

    async execute() {
        this.logger.log('Hello World!');
    }
}

new App({
    providers: [{provide: Logger, useValue: new Logger([new ConsoleTransport]}],
    controllers: [TestCommand]
}).run();
```

You can define as many dependencies as you want. The Dependency Injection Container will resolve them automatically.

---

Source: https://deepkit.io/en/documentation/app/modules

# Modules

Deepkit is highly modular and allows you to split your application into several handy modules. Each module has its own dependency injection sub-container (inheriting all parent providers), configuration, commands and much more.
In the chapter [Getting Started](https://deepkit.io/en/documentation/framework.md) you have already created one module - the root module. `new App` takes almost the same arguments as a module, because it creates the root module for you automatically in the background.

You can skip this chapter if you do not plan to split your application into submodules, or if you do not plan to make a module available as a package to others.

A module can either be defined as class module or as functional module.

```typescript title=Class Module
import { createModuleClass } from '@deepkit/app';

export class MyModule extends createModuleClass({
  //same options as new App({})
  providers: [MyService]
}) {
}
```

```typescript title=Functional Module
import { AppModule } from '@deepkit/app';

export function myModule(options: {} = {}) {
    return (module: AppModule) => {
        module.addProvider(MyService);
    };
}
```

This module can then be imported into your application or other modules.

```typescript
import { MyModule, myModule } from './module.ts'

new App({
    imports: [
        new MyModule(), //import class module
        myModule(), //import functional module
    ]
}).run();
```

You can now add features to this module as you would with `App`. The arguments of `createModule` are the same, except that imports are not available in a module definition.
For functional routes you can use the methods of `AppModule` to configure it dynamically based on your own options.

Add HTTP/RPC/CLI controllers, services, a configuration, event listeners, and various module hooks to make modules more dynamic.

## Controllers

Modules can define controllers that are processed by other modules. For example, if you add a controller with decorators from the `@deepkit/http` package, its `HttpModule` module will pick this up and register the found routes in its router. A single controller may contain several such decorators. It is up to the module author who gives you these decorators how he processes the controllers.

In Deepkit there are three packages that handles such controllers: HTTP, RPC, and CLI. See their respective chapters to learn more. Below is an example of an HTTP controller:

```typescript
import { createModuleClass } from '@deepkit/app';
import { http } from '@deepkit/http';
import { injectable } from '@deepkit/injector';

class MyHttpController {
  @http.GET('/hello)
  hello() {
    return 'Hello world!';
  }
}

export class MyModule extends createModuleClass({
  controllers: [MyHttpController]
}) {
}


//same is possible for App
new App({
  controllers: [MyHttpController]
}).run();
```

## Provider

When you define a provider in the `providers` section of your application, it is accessible throughout your application. For modules, however, these providers are automatically encapsulated in that module's dependency injection subcontainer. You must manually export each provider to make it available to another module or your application.

To learn more about how providers work, see the [Dependency Injection](https://deepkit.io/en/documentation/dependency-injection.md) chapter.

```typescript
import { createModuleClass } from '@deepkit/app';
import { http } from '@deepkit/http';
import { injectable } from '@deepkit/injector';

export class HelloWorldService {
  helloWorld() {
    return 'Hello there!';
  }
}

class MyHttpController {
  constructor(private helloService: HelloWorldService) {
  }

  @http.GET('/hello)
  hello() {
    return this.helloService.helloWorld();
  }
}

export class MyModule extends createModuleClass({
  controllers: [MyHttpController],
  providers: [HelloWorldService],
}) {
}

export function myModule(options: {} = {}) {
  return (module: AppModule) => {
    module.addController(MyHttpController);
    module.addProvider(HelloWorldService);
  };
}

//same is possible for App
new App({
  controllers: [MyHttpController],
  providers: [HelloWorldService],
}).run();
```

When a user imports this module, he has no access to `HelloWorldService` because it is encapsulated in the sub-dependency injection container of `MyModule`.

## Exports

To make providers available in the importer's module, you can include the provider's token in `exports`. This essentially moves the provider up one level into the dependency injection container of the parent module - the importer.

```typescript
import { createModuleClass } from '@deepkit/app';

export class MyModule extends createModuleClass({
  exports: [HelloWorldService],
}) {
}

export function myModule(options: {} = {}) {
  return (module: AppModule) => {
    module.addExport(HelloWorldService);
  };
}
```

If you have other providers like `FactoryProvider`, `UseClassProvider` etc., you should still use only the class type in the exports.

```typescript
import { createModuleClass } from '@deepkit/app';

export class MyModule extends createModuleClass({
  controllers: [MyHttpController]
  providers: [
    { provide: HelloWorldService, useValue: new HelloWorldService }
  ],
  exports: [HelloWorldService],
}) {
}
```

We can now import that module and use its exported service in our application code.

```typescript
import { App } from '@deepkit/app';
import { cli, Command } from '@deepkit/app';
import { HelloWorldService, MyModule } from './my-module';

@cli.controller('test')
export class TestCommand implements Command {
    constructor(protected helloWorld: HelloWorldService) {
    }

    async execute() {
        this.helloWorld.helloWorld();
    }
}

new App({
    controllers: [TestCommand],
    imports: [
        new MyModule(),
    ]
}).run();
```

Read the [Dependency Injection](https://deepkit.io/en/documentation/dependency-injection.md) chapter to learn more.


### Configuration schema

A module can have typesafe configuration options. The values of those options can be partially or completely injected to services from that module using simply the class reference or type functions like `Partial<Config, 'url'>`. To define a configuration schema write a class with properties.

```typescript
export class Config {
    title!: string; //required and needs to be provided
    host?: string; //optional

    debug: boolean = false; //default values are supported as well
}
```

```typescript
import { createModuleClass } from '@deepkit/app';
import { Config } from './module.config.ts';

export class MyModule extends createModuleClass({
  config: Config
}) {
}

export function myModule(options: Partial<Config> = {}) {
  return (module: AppModule) => {
    module.setConfigDefinition(Config).configure(options);
  };
}
```

Configuration option values can be provided either by the constructor of your module, with the `.configure()` method, or via configuration loaders (e.g. environment variables loaders).

```typescript
import { MyModule } from './module.ts';

new App({
   imports: [
       new MyModule({title: 'Hello World'}),
       myModule({title: 'Hello World'}),
   ],
}).run();
```

To dynamically change the configuration options of a imported module, you can use the `process` module hook. This is a good place to either redirect configuration options or set up an imported module depending on the current module config, or other module instance information.


```typescript
import { MyModule } from './module.ts';

export class MainModule extends createModuleClass({
}) {
    process() {
        this.getImportedModuleByClass(MyModule).configure({title: 'Changed'});
    }
}

export function myModule(options: Partial<Config> = {}) {
    return (module: AppModule) => {
        module.getImportedModuleByClass(MyModule).configure({title: 'Changed'});
    };
}
```

For the application level, it works slightly differently:

```typescript
new App({
    imports: [new MyModule({title: 'Hello World'}],
})
    .setup((module, config) => {
        module.getImportedModuleByClass(MyModule).configure({title: 'Changed'});
    })
    .run();
```

If the root application module is created from a regular module, it works similarly to regular modules.

```typescript
class AppModule extends createModuleClass({
}) {
    process() {
        this.getImportedModuleByClass(MyModule).configure({title: 'Changed'});
    }
}

App.fromModule(new AppModule()).run();
```

## Module name

All configuration options can also be changed via environment variables. This works only if the module has a name assigned. A module name can be defined via `createModule` and later changed dynamically on the instance creation. The latter pattern is useful if you have imported the same module twice and want to differentiate between them by setting a new name.

```typescript
export class MyModule extends createModuleClass({
  name: 'my'
}) {
}

export function myModule(options: Partial<Config> = {}) {
    return (module: AppModule) => {
        module.name = 'my';
    };
}
```

```typescript
import { MyModule } from './module';

new App({
    imports: [
        new MyModule(), //'my' is the default name
        new MyModule().rename('my2'), //'my2' is now the new name
    ]
}).run();
```

See the chapter [Configuration](https://deepkit.io/en/documentation/app/configuration.md) for more information on how to load configuration options from environment variables or .env files.

## Imports

Modules can import other modules to extend their functionality. In `App` you can import other modules in the module definition object via `imports: []`:

```typescript
new App({
    imports: [new Module]
}).run();
```

In regular modules, this is not possible since the module in the object definition object instance would become a global, which is usually not what you want. Instead, modules could be instantiated in module itself via the `imports` property, so that instances of each imported module is created for each new instance of your module.

```typescript
import { createModuleClass } from '@deepkit/app';

export class MyModule extends createModuleClass({}) {
  imports = [new OtherModule()];
}

export function myModule() {
  return (module: AppModule) => {
    module.addImport(new OtherModule());
  };
}
```

You can also import modules dynamically based on the configuration using the `process` hook.

```typescript
import { createModuleClass } from '@deepkit/app';

export class MyModule extends createModuleClass({}) {
  process() {
    if (this.config.xEnabled) {
      this.addImport(new OtherModule({ option: 'value' });
    }
  }
}

export function myModule(option: { xEnabled?: boolean } = {}) {
  return (module: AppModule) => {
    if (option.xEnabled) {
      module.addImport(new OtherModule());
    }
  };
}
```

## Hooks

The service container loads all modules in the order they were imported, starting at the root/application module.

During this process, the service container also executes all registered configuration loaders, calls `setupConfig` callbacks, and then validates the configuration objects of each module.

The whole process of loading the service container is as follows:

1.  For each module `T` (starting at the root)
    1. Execute configuration loaders `ConfigLoader.load(T)`.
    2. Call `T.setupConfig()`.
    3. Validate config of `T`. Abort if invalid.
    4. Call `T.process()`.  
       Here the module can modify itself based on valid configuration options. Add new imports, providers, etc.
    5. Repeat 1. for each imported module of `T`.
3. Find all registered modules.
4. Process each module found `T`.
    1. Register middlewares of `T`.
    2. Register listener of `T` in the event dispatcher.
    3. Call for all found modules from 2. `Module.processController(T, controller)`.
    4. Call for all found modules from 2. `Module.processProvider(T, token, provider)`.
    5. Repeat 3. for each imported module of `T`.
5. Run `T.postProcess()` on all modules.
6. Instantiate the bootstrap class on all modules.
7. The dependency injection container is now built.

To use hooks, you can register the `process`, `processProvider`, `postProcess` methods in your module class.

```typescript
import { createModuleClass, AppModule } from '@deepkit/app';
import { isClass } from '@deepkit/core';
import { ProviderWithScope, Token } from '@deepkit/injector';

export class MyModule extends createModuleClass({}) {
  imports = [new FrameworkModule()];

  //executed first
  process() {
    //this.config contains the fully validated config object.
    if (this.config.environment === 'development') {
      this.getImportedModuleByClass(FrameworkModule).configure({ debug: true });
    }
    this.addModule(new AnotherModule);
    this.addProvider(Service);

    //calls additional setup methods. 
    //In this case call 'method1' with given arguments when 
    //Service is instantiated by the dependency injection container.
    this.configureProvider<Service>(v => v.method1(this.config.value));
  }

  //executed for each found provider in all modules
  processController(module: AppModule<any>, controller: ClassType) {
    //HttpModule for example checks for each controller whether
    //a @http decorator was used, and if so extracts all route
    //information and puts them the router.
  }

  //executed for each found provider in all modules
  processProvider(module: AppModule<any>, token: Token, provider: ProviderWithScope) {
    //FrameworkModule for example looks for provided tokens that extend from deepkit/orm Database
    //and automatically registers them in a DatabaseRegistry so they can be used in the migration CLI commands
    //and Framework Debugger.
  }

  //executed when all modules have been processed.
  //Last chance to setup providers via module.configureProvider based on
  //information processed in process/processProvider. 
  postProcess() {

  }
}
```

## Stateful Modules

Since each module is explicitly instantiated with `new Module`, the module can have a state. This state can be injected into the dependency injection container so it is available for services.

As an example, consider the HttpModule use-case. It checks each registered controller in the whole application to have certain @http decorators, and if so, puts the controller in a registry. This registry is injected to the Router, which, once instantiated, extracts all route information of those controllers and register them.

```typescript
class Registry {
    protected controllers: { module: AppModule<any>, classType: ClassType }[] = [];
        
    register(module: AppModule<any>, controller: ClassType) {
        this.controllers.push({ module, classType: controller });
    }
        
    get(classType: ClassType) {
        const controller = this.controllers.find(v => v.classType === classType);
        if (!controller) throw new Error('Controller unknown');
        return controller;
    }
}
        
class Router {
    constructor(
        protected injectorContext: InjectorContext,
        protected registry: Registry
    ) {
    }
        
    getController(classType: ClassType) {
        //find classType and module for given controller classType
        const controller = this.registry.get(classType);
        
        //here the controller will be instantiated. If it was already
        //instantiated, the old instanced will be returned (if the provider was not transient: true)
        return injector.get(controller.classType, controller.module);
    }
}
        
class HttpModule extends createModuleClass({
    providers: [Router],
    exports: [Router],
}) {
    protected registry = new Registry;
        
    process() {
        this.addProvider({ provide: Registry, useValue: this.registry });
    }
        
    processController(module: AppModule<any>, controller: ClassType) {
        //controllers need to be put into the module's providers by the controller consumer
        if (!module.isProvided(controller)) module.addProvider(controller);
        this.registry.register(module, controller);
    }
}
        
class MyController {}
        
const app = new App({
    controllers: [MyController],
    imports: [new HttpModule()]
});
        
const myController = app.get(Router).getController(MyController);
```

## For root

The `root` property allows you to move the dependency injection container of a module into the root application's container. This makes every service available from the module automatically available in the root application itself. It basically moves each provider (controller, event listener, provider) into the root container. This could lead to dependency clashes, so should only be used for a module that has really only globals. You should prefer exporting each provider manually instead.

If you build a library that can be used by many modules, you should avoid using `root`, as it could clash with provider tokens from other libraries. For example, if this library module imports a `foo` module that defines a service, and you reconfigure some services to your need, and the user's application imports the same `foo` module, the user receives your reconfigured services. For many simpler use cases this might be fine though.

```typescript
import { createModuleClass } from '@deepkit/app';

export class MyModule extends createModuleClass({}) {
  root = true;
}
```

You can also change the `root` property of a third-party module, by using `forRoot()`.

```typescript
new App({
    imports: [new ThirdPartyModule().forRoot()],
}).run();
```

## Injector Context

The InjectorContext is the dependency injection container. It allows you to request/instantiate services from your own or other modules. This is necessary if for example you have stored a controller in `processControllers` and want to correctly instantiate them.

---

Source: https://deepkit.io/en/documentation/app/services

# Services


Service is a broad category encompassing any value, function, or feature that an application needs. A service is typically a class with a narrow, well-defined purpose. It should do something specific and do it well.

A service in Deepkit (and in most other JavaScript/TypeScript frameworks) is a simple class registered in a module using a provider. The simplest provider is the class provider, which specifies only the class itself and nothing else. It then becomes a singleton in the dependency injection container of the module where it was defined.

Services are handled and instantiated by the dependency injection container and thus can be imported and used in other services, in controllers, and event listeners using constructor injection or property injection. See the chapter [Dependency injection](https://deepkit.io/en/documentation/dependency-injection) for more details.

To create a simple service, you write a class with a purpose:


```typescript
export interface User {
    username: string;
}

export class UserManager {
    users: User[] = [];

    addUser(user: User) {
        this.users.push(user);
    }
}
```

And either register it in your application, or in a module:

```typescript
new App({
    providers: [UserManager]
}).run();
```

After doing so you can use this service in controllers, other services, or event listeners. For example, let's use this service in a CLI command or HTTP route:


```typescript
import { App } from '@deepkit/app';
import { HttpRouterRegistry } from '@deepkit/http';

const app = new App({
    providers: [UserManager],
    imports: [new FrameworkModule({debug: true})]
});

app.command('test', (userManager: UserManager) => {
    for (const user of userManager.users) {
        console.log('User: ', user.username);
    }
});

const router = app.get(HttpRouterRegistry);

router.get('/', (userManager: UserManager) => {
    return userManager.users;
})

app.run();
```

A service is a fundamental building block in Deepkit and is not restricted to classes. In fact, a service can be any value, function, or feature needed by an application. To learn more about, see chapter [Dependency Injection](https://deepkit.io/en/documentation/dependency-injection).

---

Source: https://deepkit.io/en/documentation/app/events

# Event System

An event system allows application components within the same process to communicate by sending and listening to events. This aids in code modularization by facilitating message exchanges between functions that might not directly be aware of each other.

The application or library provides an opportunity to execute additional functions at specific points during its operation. These additional functions register themselves as what are termed "event listeners".

An event can take various forms:

- The application starts up or shuts down.
- A new user is created or deleted.
- An error is thrown.
- A new HTTP request is received.

The Deepkit Framework and its associated libraries offer a range of events that users can listen to and respond to. However, users also have the flexibility to create as many custom events as needed, allowing for modular expansion of the application.

## Usage

If you use a Deepkit app, the event system is already included and ready to use.

```typescript
import { App, onAppExecute } from '@deepkit/app';

const app = new App();

app.listen(onAppExecute, async (event) => {
    console.log('MyEvent triggered!');
});

app.run();
```

Events can be registered either by using the `listen()` method or a class using the `@eventDispatcher.listen` decorator:

```typescript
import { App, onAppExecute } from '@deepkit/app';
import { eventDispatcher } from '@deepkit/event';

class MyListener {
    @eventDispatcher.listen(onAppExecute)
    onMyEvent(event: typeof onAppExecute.event) {
        console.log('MyEvent triggered!');
    }
}

const app = new App({
    listeners: [MyListener],
});
app.run();
```

## Event Token

At the core of Deepkit's event system are Event Tokens. These are unique objects that specify both the event ID and the type of event. An event token serves two primary purposes:

- It acts as a trigger for an event.
- It listens to the event it triggers.

When an event is initiated using an event token, that token's owner is effectively recognized as the source of the event. The token determines the data associated with the event and specifies if asynchronous event listeners can be utilized.

```typescript
import { EventToken } from '@deepkit/event';

const MyEvent = new EventToken('my-event');

app.listen(MyEvent, (event) => {
    console.log('MyEvent triggered!');
});

//trigger via app reference
await app.dispatch(MyEvent);

//or use the EventDispatcher, App's DI container injects it automatically
app.command('test', async (dispatcher: EventDispatcher) => {
    await dispatcher.dispatch(MyEvent);
});
```

### Creating Custom Event Data:

Using `DataEventToken` from @deepkit/event:

```typescript
import { DataEventToken } from '@deepkit/event';

class User {
}

const MyEvent = new DataEventToken<User>('my-event');
```

Extending BaseEvent:

```typescript
class MyEvent extends BaseEvent {
    user: User = new User;
}

const MyEventToken = new EventToken<MyEvent>('my-event');
```

## Functional Listeners

Functional listeners allow users to register a simple function callback with the dispatcher directly. Here's how:

```typescript
app.listen(MyEvent, (event) => {
    console.log('MyEvent triggered!');
});
```

If you wish to introduce additional arguments like `logger: Logger`, they are automatically injected by the dependency injection system, thanks to Deepkit's runtime type reflection.

```typescript
app.listen(MyEvent, (event, logger: Logger) => {
    console.log('MyEvent triggered!');
});
```

Note that the first argument has to be the event itself. You can not avoid this argument.

If you use `@deepkit/app`, you can also use app.listen() to register a functional listener.

```typescript
import { App } from '@deepkit/app';

new App()
    .listen(MyEvent, (event) => {
        console.log('MyEvent triggered!');
    })
    .run();
```

## Class-based Listeners

Class listeners are classes adorned with decorators. They offer a structured way to listen to events.

```typescript
import { App } from '@deepkit/app';

class MyListener {
    @eventDispatcher.listen(UserAdded)
    onUserAdded(event: typeof UserAdded.event) {
        console.log('User added!', event.user.username);
    }
}

new App({
    listeners: [MyListener],
}).run();
```

For class listeners, dependency injection works through either the method arguments or the constructor.

## Dependency Injection

Deepkit's event system boasts a powerful dependency injection mechanism. When using functional listeners, additional arguments get automatically injected thanks to the runtime type reflection system. Similarly, class-based listeners support dependency injection through either the constructor or method arguments.

For example, in the case of a functional listener, if you add an argument like `logger: Logger`, the correct Logger instance gets automatically provided when the function gets called.

```typescript
import { App } from '@deepkit/app';
import { Logger } from '@deepkit/logger';

new App()
    .listen(MyEvent, (event, logger: Logger) => {
        console.log('MyEvent triggered!');
    })
    .run();
```

## Event Propagation

Every event object comes equipped with a stop() function, allowing you to control the propagation of the event. If an event is halted, no subsequent listeners (in the order they were added) will be executed. This provides granular control over the execution and handling of events, especially useful in scenarios where certain conditions may require the halting of event processing.

For instance:

```typescript
dispatcher.listen(MyEventToken, (event) => {
    if (someCondition) {
        event.stop();
    }
    // Further processing
});
```

With the Deepkit framework's event system, developers can create modular, scalable, and maintainable applications with ease. Understanding the event system provides the flexibility to tailor the application's behavior based on specific occurrences or conditions.

## Framework Events

Deepkit Framework itself has several events from the application server that you can listen for.

_Functional Listener_

```typescript
import { onServerMainBootstrap } from '@deepkit/framework';
import { onAppExecute } from '@deepkit/app';

new App({
    imports: [new FrameworkModule]
})
    .listen(onAppExecute, (event) => {
        console.log('Command about to execute');
    })
    .listen(onServerMainBootstrap, (event) => {
        console.log('Server started');
    })
    .run();
```

| Name                        | Description                                                                                                                     |
|-----------------------------|---------------------------------------------------------------------------------------------------------------------------------|
| onServerBootstrap           | Called only once for application server bootstrap (for main process and workers).                                               |
| onServerBootstrapDone       | Called only once for application server bootstrap (for main process and workers) as soon as the application server has started. |
| onServerMainBootstrap       | Called only once for application server bootstrap (in the main process).                                                        |
| onServerMainBootstrapDone   | Called only once for application server bootstrap (in the main process) as soon as the application server has started.          |
| onServerWorkerBootstrap     | Called only once for application server bootstrap (in the worker process).                                                      |
| onServerWorkerBootstrapDone | Called only once for application server bootstrap (in the worker process) as soon as the application server has started.        |
| onServerShutdownEvent       | Called when application server shuts down (in master process and each worker).                                                  |
| onServerMainShutdown        | Called when application server shuts down in the main process.                                                                  |
| onServerWorkerShutdown      | Called when application server shuts down in the worker process.                                                                |
| onAppExecute                | When a command is about to be executed.                                                                                         |
| onAppExecuted               | When a command is successfully executed.                                                                                        |
| onAppError                  | When a command failed to execute                                                                                                |
| onAppShutdown               | When the application is about to shut down.                                                                                     |

## Low Level API

Below is an example of the low-level API from @deepkit/event. When using the Deepkit App, event listeners are not registered directly via the EventDispatcher, but rather through modules. But you can still use the low-level API if you want to.

```typescript
import { EventDispatcher, EventToken } from '@deepkit/event';

//first argument can be a injector context to resolve dependencies for dependency injection
const dispatcher = new EventDispatcher();
const MyEvent = new EventToken('my-event');

dispatcher.listen(MyEvent, (event) => {
    console.log('MyEvent triggered!');
});
dispatcher.dispatch(MyEvent);

```

### Installation

The event system is included in @deepkit/app. If you want to use it standalone, you can install it manually:

See [Event](https://deepkit.io/en/documentation/package/event.md) for installation instructions.

---

Source: https://deepkit.io/en/documentation/app/logger

# Logger

Deepkit Logger is a standalone library with a primary Logger class that you can use to log information. This class is automatically available in the Dependency Injection container of your Deepkit application.

The `Logger` class has several methods, each of which behaves like `console.log`.

| Name            | Log Level           | Level id |
|-----------------|---------------------|----------|
| logger.error()  | Error               | 1        |
| logger.warning()| Warning             | 2        |
| logger.log()    | Default log         | 3        |
| logger.info()   | Special information | 4        |
| logger.debug()  | Debug information   | 5        |


By default, a logger has `info` level, i.e. it processes only info messages and more (i.e. log, warning, error, but not debug). To change the log level call for example `logger.level = 5`.

## Use in the application

To use the logger in your Deepkit application, you can simply inject `Logger` into your services or controllers.

```typescript
import { Logger } from '@deepkit/logger';
import { App } from '@deepkit/app';

const app = new App();
app.command('test', (logger: Logger) => {
    logger.log('This is a <yellow>log message</yellow>');
});

app.run();
```

## Colors

The logger supports colored log messages. You can provide colors by using XML tags that surround the text you want to appear in color.

```typescript
const username = 'Peter';
logger.log(`Hi <green>${username}</green>`);
```

For transporters that do not support colors, the color information is automatically removed. In the default transporter (`ConsoleTransport`) the color is displayed. The following colors are available: `black`, `red`, `green`, `blue`, `cyan`, `magenta`, `white` and `grey`/`gray`.

## Transporter

You can configure a single transporter or multiple transporters. In a Deepkit application, the `ConsoleTransport` transporter is configured automatically. To configure additional transporters, you can use [Setup Calls](https://deepkit.io/en/documentation/app/dependency-injection.md#di-setup-calls):

```typescript
import { Logger, LoggerTransport } from '@deepkit/logger';

export class MyTransport implements LoggerTransport {
    write(message: string, level: LoggerLevel, rawMessage: string) {
        process.stdout.write(JSON.stringify({message: rawMessage, level, time: new Date}) + '\n');
    }

    supportsColor() {
        return false;
    }
}

new App()
    .setup((module, config) => {
        module.configureProvider<Logger>(v => v.addTransport(new MyTransport));
    })
    .run();
```

To replace all transporters with a new set of transporters, use `setTransport`:

```typescript
import { Logger } from '@deepkit/logger';

new App()
.setup((module, config) => {
    module.configureProvider<Logger>(v => v.setTransport([new MyTransport]));
})
.run();
```

```typescript
import { Logger, JSONTransport } from '@deepkit/logger';

new App()
    .setup((module, config) => {
        module.configureProvider<Logger>(v => v.setTransport([new JSONTransport]));
    })
    .run();
```

## Scoped Logger

Scoped loggers add an arbitrary area name to each log entry, which can be helpful in determining which subarea of your application the log entry originated from.

```typescript
const scopedLogger = logger.scoped('database');
scopedLogger.log('Query', query);
```

There is also a `ScopedLogger` type that you can use to inject scoped loggers into your services.

```typescript
import { ScopedLogger } from '@deepkit/logger';

class MyService {
    constructor(protected logger: ScopedLogger) {}
    doSomething() {
        this.logger.log('This is wild');
    }
}
```

All messages from a scoped logger are prefixed with the `MyService` scope name now.

## Formatter

With formatters, you can change the message format, e.g. add the timestamp. When an application is started via `server:start`, a `DefaultFormatter` is automatically added (which adds timestamp, range and log level) if no other formatter is available.

## Context Data

To add contextual data to a log entry, add a simple object literal as the last argument. Only log calls with at least two arguments can contain contextual data.

```typescript
const query = 'SELECT *';
const user = new User;
logger.log('Query', {query, user}); //last argument is context data
logger.log('Another', 'wild log entry', query, {user}); //last argument is context data

logger.log({query, user}); //this is not handled as context data.
```

---

Source: https://deepkit.io/en/documentation/app/configuration

# Configuration

In Deepkit applications, modules and your application can have configuration options. 
For example, a configuration can consist of database URLs, passwords, IPs, and so on. Services, HTTP/RPC/CLI controllers, and template functions can read these configuration options via dependency injection.

A configuration can be defined by defining a class with properties. This is a typesafe way to define a configuration for your entire application, and its values are automatically serialized and validated.

## Example

```typescript
import { MinLength } from '@deepkit/type';
import { App } from '@deepkit/app';

class Config {
    pageTitle: string & MinLength<2> = 'Cool site';
    domain: string = 'example.com';
    debug: boolean = false;
}

const app = new App({
    config: Config
});


app.command('print-config', (config: Config) => {
    console.log('config', config);
})

app.run();
```

```sh
$ curl http://localhost:8080/
Hello from Cool site via example.com
```

When no configuration loader is used, the default values will be used. To change the configuration, you can either use the `app.configure({domain: 'localhost'})` method or use an environment configuration loader.

## Set configuration values

By default, no values are overwritten, so default values are used. There are several ways to set configuration values.

* Via `app.configure({})`
* Environment variables for each option
* Environment variable via JSON
* dotenv-Files

You can use several methods to load the configuration at the same time. The order in which they are called is important.

### Environment variables

To allow setting each configuration option via its own environment variable, use `loadConfigFromEnv`. The default prefix is `APP_`, but you can change it. It also automatically loads `.env` files. By default, it uses an uppercase naming strategy, but you can change that too.

For configuration options like `pageTitle` above, you can use `APP_PAGE_TITLE="Other Title"` to change the value.

```typescript
new App({
    config: config,
    controllers: [MyWebsite],
})
    .loadConfigFromEnv({prefix: 'APP_'})
    .run();
```

```sh
APP_PAGE_TITLE="Other title" ts-node app.ts server:start
```

### JSON environment variable

To change multiple configuration options via a single environment variable, use `loadConfigFromEnvVariable`. The first argument is the name of the environment variable.

```typescript
new App({
    config: config,
    controllers: [MyWebsite],
})
    .loadConfigFromEnvVariable('APP_CONFIG')
    .run();
```

```sh
APP_CONFIG='{"pageTitle": "Other title"}' ts-node app.ts server:start
```

### DotEnv Files

To change multiple configuration options via a dotenv file, use `loadConfigFromEnv`. The first argument is either a path to a dotenv (relative to `cwd`) or multiple paths. If it is an array, each path is tried until an existing file is found.

```typescript
new App({
    config: config,
    controllers: [MyWebsite],
})
    .loadConfigFromEnv({envFilePath: ['production.dotenv', 'dotenv']})
    .run();
```

```sh
$ cat dotenv
APP_PAGE_TITLE=Other title
$ ts-node app.ts server:start
```

### Module Configuration

Each imported module can have a module name. This name is used for the configuration paths used above.

For example, for configuring environment variables, the path for the `FrameworkModule` option port is `FRAMEWORK_PORT`. All names are written in uppercase by default. If a prefix of `APP_` is used, the port can be changed via the following:

```sh
$ APP_FRAMEWORK_PORT=9999 ts-node app.ts server:start
2021-06-12T18:59:26.363Z [LOG] Start HTTP server, using 1 workers.
2021-06-12T18:59:26.365Z [LOG] HTTP MyWebsite
2021-06-12T18:59:26.366Z [LOG]     GET / helloWorld
2021-06-12T18:59:26.366Z [LOG] HTTP listening at http://localhost:9999/
```

In dotenv files it would also be `APP_FRAMEWORK_PORT=9999`.

In JSON environment variables via `loadConfigFromEnvVariable('APP_CONFIG')` on the other hand, it is the structure of the actual configuration class. `framework` becomes an object.

```sh
$ APP_CONFIG='{"framework": {"port": 9999}}' ts-node app.ts server:start
```

This works the same for all modules. No module prefix is required for your application configuration option (`new App`).


## Configuration class

```typescript
import { MinLength } from '@deepkit/type';

export class Config {
    title!: string & MinLength<2>; //this makes it required and needs to be provided
    host?: string;

    debug: boolean = false; //default values are supported as well
}
```

```typescript
import { createModuleClass } from '@deepkit/app';
import { Config } from './module.config.ts';

export class MyModule extends createModuleClass({
  config: Config
}) {
}
```

The values for the configuration options can be provided either in the constructor of the module, with the `.configure()` method, or via configuration loaders (e.g. environment variable loader).

```typescript
import { MyModule } from './module.ts';

new App({
   imports: [new MyModule({title: 'Hello World'})],
}).run();
```

To dynamically change the configuration options of an imported module, you can use the `process` hook. This is a good place to either redirect configuration options or set up an imported module depending on the current module configuration or other module instance information.

```typescript
import { MyModule } from './module.ts';

export class MainModule extends createModuleClass({
}) {
    process() {
        this.getImportedModuleByClass(MyModule).configure({title: 'Changed'});
    }
}
```

At the application level, it works a little differently:

```typescript
new App({
    imports: [new MyModule({title: 'Hello World'}],
})
    .setup((module, config) => {
        module.getImportedModuleByClass(MyModule).configure({title: 'Changed'});
    })
    .run();
```

When the root application module is created from a regular module, it works similarly to regular modules.

```typescript
class AppModule extends createModuleClass({
}) {
    process() {
        this.getImportedModuleByClass(MyModule).configure({title: 'Changed'});
    }
}

App.fromModule(new AppModule()).run();
```

## Read configuration values

To use a configuration option in a service, you can use normal dependency injection. It is possible to inject either the entire configuration object, a single value, or a portion of the configuration.

### Partial

To inject only a subset of the configuration values, use the `Pick` type.

```typescript
import { Config } from './module.config';

export class MyService {
     constructor(private config: Pick<Config, 'title' | 'host'}) {
     }

     getTitle() {
         return this.config.title;
     }
}


//In unit tests, it can be instantiated via
new MyService({title: 'Hello', host: '0.0.0.0'});

//or you can use type aliases
type MyServiceConfig = Pick<Config, 'title' | 'host'};
export class MyService {
     constructor(private config: MyServiceConfig) {
     }
}
```

### Single value

To inject only a single value, use the index access operator.

```typescript
import { Config } from './module.config';

export class MyService {
     constructor(private title: Config['title']) {
     }

     getTitle() {
         return this.title;
     }
}
```

### All

To inject all config values, use the class as dependency.

```typescript
import { Config } from './module.config';

export class MyService {
     constructor(private config: Config) {
     }

     getTitle() {
         return this.config.title;
     }
}
```

---

Source: https://deepkit.io/en/documentation/framework

# Deepkit Framework

Deepkit Framework is based on [Deepkit App](https://deepkit.io/en/documentation/app.md) in `@deepkit/app` and provides the `FrameworkModule` module in `@deepkit/framework`, which can be imported in your application.

The `App` abstraction brings:

- CLI commands
- Configuration loading (environment, dotfiles, custom)
- Module system
- Powerful Service Container
- Registry and hooks for controllers, providers, listeners, and more

The `FrameworkModule` module brings additional features:

- Application server
    - HTTP server
    - RPC server
    - Multi-process load balancing
    - SSL
- Debugging CLI commands
- Database Migration configuration/commands
- Debugging/Profiler GUI via `{debug: true}` option
- Interactive API documentation (like Swagger)
- Providers for DatabaseRegistry, ProcessLocking, Broker, Sessions
- Integration Test APIs

You can write applications with or without the `FrameworkModule`.

## Installation

Deepkit Framework is based on [Deepkit App](https://deepkit.io/en/documentation/app.md). Make sure you followed its installation instructions.
If so you can install Deepkit framework and import the `FrameworkModule` in your `App`. 

```sh
npm install @deepkit/framework
```

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';

const app = new App({
    imports: [new FrameworkModule({ debug: true })]
});

app.command('test', (logger: Logger) => {
    logger.log('Hello World!');
});

app.run();
```

Since the app now imports the `FrameworkModule`, we see there are more commands available grouped into topics.

One of them is `server:start`, which starts the HTTP server. To use it, we have to register at least one HTTP route.

```typescript
import { App } from '@deepkit/app';
import { HttpRouterRegistry } from '@deepkit/http';

const app = new App({
    imports: [new FrameworkModule({ debug: true })]
});

app.command('test', (logger: Logger) => {
    logger.log('Hello World!');
});


const router = app.get(HttpRouterRegistry);

router.get('/', () => {
    return 'Hello World';
})

app.run();
```

When you execute the `server:start` command again, you will see that the HTTP server is now started and the route `/` is available.

```sh
$ ./node_modules/.bin/ts-node ./app.ts server:start
```

```sh
$ curl http://localhost:8080/
Hello World
```

To serve requests please read chapter [HTTP](https://deepkit.io/en/documentation/http.md) or [RPC](https://deepkit.io/en/documentation/rpc.md). In chapter [App](https://deepkit.io/en/documentation/app.md) you can learn more about CLI commands.

## App

The `App` class is the main entry point for your application. It is responsible for loading all modules, configuration, and starting the application.
It is also responsible for loading all CLI commands and executing them. Modules like FrameworkModule provide additional commands, register event listeners,
provide controllers for HTTP/RPC, service providers and so on.

This `app` object can also be used to access the Dependency Injection container without running a CLI controller.

```typescript
const app = new App({
    imports: [new FrameworkModule]
});

//get access to all registered services
const eventDispatcher = app.get(EventDispatcher);
```

You can retrieve the `EventDispatcher` because the `FrameworkModule` registers it as a service provider like many other (Logger, ApplicationServer, and [much more](https://github.com/deepkit/deepkit-framework/blob/master/packages/framework/src/module.ts)).

You can also register your own service.

```typescript

class MyService {
    constructor(private logger: Logger) {
    }

    helloWorld() {
        this.logger.log('Hello World');
    }
}

const app = new App({
    providers: [MyService],
    imports: [new FrameworkModule]
});

const service = app.get(MyService);

service.helloWorld();
```

### Debugger

The configuration values of your application and all modules can be displayed in the debugger. Enable the debug option in `FrameworkModule` and open `http://localhost:8080/_debug/configuration`.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';

new App({
    config: Config,
    controllers: [MyWebsite],
    imports: [
        new FrameworkModule({
            debug: true,
        })
    ]
}).run();
```

![Debugger Configuration](https://deepkit.io/assets/documentation/framework/debugger-configuration.png)

You can also use `ts-node app.ts app:config` to display all available configuration options, the active value, their default value, description and data type.

```sh
$ ts-node app.ts app:config
Application config
┌─────────┬───────────────┬────────────────────────┬────────────────────────┬─────────────┬───────────┐
│ (index) │     name      │         value          │      defaultValue      │ description │   type    │
├─────────┼───────────────┼────────────────────────┼────────────────────────┼─────────────┼───────────┤
│    0    │  'pageTitle'  │     'Other title'      │      'Cool site'       │     ''      │ 'string'  │
│    1    │   'domain'    │     'example.com'      │     'example.com'      │     ''      │ 'string'  │
│    2    │    'port'     │          8080          │          8080          │     ''      │ 'number'  │
│    3    │ 'databaseUrl' │ 'mongodb://localhost/' │ 'mongodb://localhost/' │     ''      │ 'string'  │
│    4    │    'email'    │         false          │         false          │     ''      │ 'boolean' │
│    5    │ 'emailSender' │       undefined        │       undefined        │     ''      │ 'string?' │
└─────────┴───────────────┴────────────────────────┴────────────────────────┴─────────────┴───────────┘
Modules config
┌─────────┬──────────────────────────────┬─────────────────┬─────────────────┬────────────────────────────────────────────────────────────────────────────────────────────────────┬────────────┐
│ (index) │           name               │      value      │  defaultValue   │                                            description                                             │    type    │
├─────────┼──────────────────────────────┼─────────────────┼─────────────────┼────────────────────────────────────────────────────────────────────────────────────────────────────┼────────────┤
│    0    │       'framework.host'       │   'localhost'   │   'localhost'   │                                                 ''                                                 │  'string'  │
│    1    │       'framework.port'       │      8080       │      8080       │                                                 ''                                                 │  'number'  │
│    2    │    'framework.httpsPort'     │    undefined    │    undefined    │ 'If httpsPort and ssl is defined, then the https server is started additional to the http-server.' │ 'number?'  │
│    3    │    'framework.selfSigned'    │    undefined    │    undefined    │           'If for ssl: true the certificate and key should be automatically generated.'            │ 'boolean?' │
│    4    │ 'framework.keepAliveTimeout' │    undefined    │    undefined    │                                                 ''                                                 │ 'number?'  │
│    5    │       'framework.path'       │       '/'       │       '/'       │                                                 ''                                                 │  'string'  │
│    6    │     'framework.workers'      │        1        │        1        │                                                 ''                                                 │  'number'  │
│    7    │       'framework.ssl'        │      false      │      false      │                                       'Enables HTTPS server'                                       │ 'boolean'  │
│    8    │    'framework.sslOptions'    │    undefined    │    undefined    │                   'Same interface as tls.SecureContextOptions & tls.TlsOptions.'                   │   'any'    │
...
```

## Application Server

## File Structure

## Auto-CRUD

## Events

Deepkit framework comes with various event tokens on which event listeners can be registered.

See the [Events](https://deepkit.io/en/documentation/app/events.md) chapter to learn more about how events work.

### Dispatch Events

Events are sent via the `EventDispatcher` class. In a Deepkit app, this can be provided via dependency injection.

```typescript
import { cli, Command } from '@deepkit/app';
import { EventDispatcher } from '@deepkit/event';

@cli.controller('test')
export class TestCommand implements Command {
    constructor(protected eventDispatcher: EventDispatcher) {
    }

    async execute() {
        this.eventDispatcher.dispatch(UserAdded, new UserEvent({ username: 'Peter' }));
    }
}
```

---

Source: https://deepkit.io/en/documentation/framework/database

# Database

Deepkit has its own powerful database abstraction library called Deepkit ORM. It is an Object-Relational Mapping (ORM) library that facilitates work with SQL databases and MongoDB.

Although you can use any database library, we recommend Deepkit ORM as it is the fastest TypeScript database abstraction library that is perfectly integrated with the Deepkit framework and has many features that will improve your workflow and efficiency.

This chapter explains how to use Deepkit ORM with your Deepkit app. To get all the information about Deepkit ORM, see the [ORM](https://deepkit.io/en/documentation/orm.md) chapter.

## Database Classes

The simplest way to use the `Database` object of Deepkit ORM within the application is to register a class that derives from it.

```typescript
import { Database } from '@deepkit/orm';
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { User } from './models';

export class SQLiteDatabase extends Database {
    constructor() {
        super(
            new SQLiteDatabaseAdapter('/tmp/myapp.sqlite'), 
            [User]
        );
    }
}
```

Create a new class and in its constructor specify the adapter with its parameters and add to the second parameter all entity models that should be connected to this database.

You can now register this database class as a provider. We also enable `migrateOnStartup` which will automatically create all tables in your database at bootstrap. This is ideal for rapid prototyping, but is not recommended for a serious project or production setup. Normal database migrations should then be used here.

We also enable `debug`, which allows us to open the debugger when the application's server is started and manage your database models directly in its built-in ORM browser.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { SQLiteDatabase } from './database.ts';

new App({
    providers: [SQLiteDatabase],
    imports: [
        new FrameworkModule({
            migrateOnStartup: true,
            debug: true,
        })
    ]
}).run();
```

You can now access `SQLiteDatabase` anywhere using Dependency Injection:

```typescript
import { SQLiteDatabase } from './database.ts';

export class Controller {
    constructor(protected database: SQLiteDatabase) {}

    @http.GET()
    async startPage(): Promise<User[]> {
        //return all users
        return await this.database.query(User).find();
    }
}
```

## Configuration

In many cases you want your connection credentials to be configurable. For example, you want to use a different database for testing than for production. You can do this by using the `config` option of the `Database` class.

```typescript
//database.ts
import { Database } from '@deepkit/orm';
import { PostgresDatabaseAdapter } from '@deepkit/sqlite';
import { User } from './models';

type DbConfig = Pick<AppConfig, 'databaseHost', 'databaseUser', 'databasePassword'>;

export class MainDatabase extends Database {
    constructor(config: DbConfig) {
        super(new PostgresDatabaseAdapter({
            host: config.databaseHost,
            user: config.databaseUser,
            password: config.databasePassword,
        }), [User]);
    }
}
```

```typescript
//config.ts
export class AppConfig {
    databaseHost: string = 'localhost';
    databaseUser: string = 'postgres';
    databasePassword: string = '';
}
```

```typescript
//app.ts
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { MainDatabase } from './database.ts';
import { AppConfig } from './config.ts';

const app = new App({
    config: AppConfig,
    providers: [MainDatabase],
    imports: [
        new FrameworkModule({
            migrateOnStartup: true,
            debug: true,
        })
    ]
});
app.loadConfigFromEnv({prefix: 'APP_', namingStrategy: 'upper', envFilePath: ['local.env', 'prod.env']});
app.run();
```


Now, since we use loadConfigFromEnv, we can set the database credentials via environment variables.

```sh
APP_DATABASE_HOST=localhost APP_DATABASE_USER=postgres ts-node app.ts server:start
```

or in the `local.env` file and start `ts-node app.ts server:start` without any previously set environment variables.

```sh
APP_DATABASE_HOST=localhost
APP_DATABASE_USER=postgres
```

## Multiple Databases

You can add as many database classes as you like and name them as you like. Be sure to change the name of each database so that it doesn't conflict with others when you use Deepkit ORM Browser.

## Manage Data

You now have everything set up to manage your database data with the Deepkit ORM Browser. To open Deepkit ORM Browser and manage the content, write all the steps from above in the `app.ts` file and start the server.

```sh
$ ts-node app.ts server:start
2021-06-11T15:08:54.330Z [LOG] Start HTTP server, using 1 workers.
2021-06-11T15:08:54.333Z [LOG] Migrate database default
2021-06-11T15:08:54.336Z [LOG] RPC DebugController deepkit/debug/controller
2021-06-11T15:08:54.337Z [LOG] RPC OrmBrowserController orm-browser/controller
2021-06-11T15:08:54.337Z [LOG] HTTP OrmBrowserController
2021-06-11T15:08:54.337Z [LOG]     GET /_orm-browser/query httpQuery
2021-06-11T15:08:54.337Z [LOG] HTTP StaticController
2021-06-11T15:08:54.337Z [LOG]     GET /_debug/:any serviceApp
2021-06-11T15:08:54.337Z [LOG] HTTP listening at http://localhost:8080/
```

You can now open http://localhost:8080/_debug/database/default.

![Debugger Database](https://deepkit.io/assets/documentation/framework/debugger-database.png)

You can see the ER (entity relationship) diagram. At the moment only one entity is available. If you add more with relationships, you will see all the information at a glance.

If you click on `User` in the left sidebar, you can manage its content. Click the `+` icon and change the title of the new record. After you have changed the required values (such as the user name), click `Confirm`. This will commit all changes to the database and make them permanent. The auto increment ID will be assigned automatically.

![Debugger Database User](https://deepkit.io/assets/documentation/framework/debugger-database-user.png)

## Learn More

To learn more about how `SQLiteDatabase` works, please read the chapter [Database](https://deepkit.io/en/documentation/orm.md) and its subchapters, such as querying data, manipulating data via sessions, defining relations and much more.
Please note that the chapters there refer to the standalone library `@deepkit/orm` and do not include documentation about the part of the deepkit framework you read above in this chapter. In the standalone library, you instantiate your database class manually, for example via `new SQLiteDatabase()`. However, in your Deepkit app, this is done automatically using the Dependency Injection container.

## Migration

The Deepkit framework has a powerful migration system that allows you to create, execute and revert migrations. The migration system is based on the Deepkit ORM library and is therefore perfectly integrated into the framework.

The `FrameworkModule` provides several commands to manage migrations.

- `migration:create` - Generates a new migration file based on a database diff
- `migration:pending` - Shows pending migration files
- `migration:up` - Executes pending migration files.
- `migration:down` - Executes down migration, reverting old migration files


```sh
ts-node app.ts migration:create --migrationDir src/migrations
```

A new migration file is created in `migrations`. This folder is the default directory configured in FrameworkModule. To change it change the configuration either through environment variables (as descripted in the [Configuration](https://deepkit.io/en/documentation/app/configuration.md) chapter) or by passing the `migrationDir` option to the `FrameworkModule` constructor.

```typescript
new FrameworkModule({
    migrationDir: 'src/migrations',
})
```

The newly created migration file contains now the up and down methods based on the difference between the entities defined in your TypeScript app and the configured database. 
You can now modify the up method to your needs. The down method is automatically generated based on the up method.
You commit this file to your repository so that other developers can also execute it.

### Pending Migrations

```sh
ts-node app.ts migration:pending --migrationDir src/migrations
```

This shows all pending migrations. If you have a new migration file that is not executed yet, it will be listed here.

### Executing Migrations

```sh
ts-node app.ts migration:up --migrationDir src/migrations
```

This executes the next pending migration.

### Reverting Migrations

```sh
ts-node app.ts migration:down --migrationDir src/migrations
```

This reverts the last executed migration.

### Fake migrations

Let's say you wanted to execute a migration (up or down), but it failed. You fixed the issue manually, but now you can't execute the migration again, because it's already executed. You can use the `--fake` option to fake the migration, so that it's marked as executed in the database without actually executing it. This way you can execute the next pending migration.

```sh
ts-node app.ts migration:up --migrationDir src/migrations --fake
```

---

Source: https://deepkit.io/en/documentation/framework/testing

# Testing

The services and controllers in the Deepkit framework are designed to support SOLID and clean code that is well-designed, encapsulated, and separated. These features make the code easy to test.

This documentation shows you how to set up a testing framework named [Jest](https://jestjs.io) with `ts-jest`. To do this, run the following command to install `jest` and `ts-jest`.

```sh
npm install jest ts-jest @types/jest
```

Jest needs a few configuration options to know where to find the test suits and how to compile the TS code. Add the following configuration to your `package.json`:

```json title=package.json
{
  ...,

  "jest": {
    "transform": {
      "^.+\\.(ts|tsx)$": "ts-jest"
    },
    "testEnvironment": "node",
    "testMatch": [
      "**/*.spec.ts"
    ]
  }
}
```

Your test files should be named `.spec.ts`. Create a `test.spec.ts` file with the following content.

```typescript
test('first test', () => {
    expect(1 + 1).toBe(2);
});
```

You can now use the jest command to run all your test suits at once.

```sh
$ node_modules/.bin/jest
 PASS  ./test.spec.ts
  ✓ first test (1 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.23 s, estimated 1 s
Ran all test suites.
```

Please read the [Jest-Dokumentation](https://jestjs.io) to learn more about how the Jest CLI tool works and how you can write more sophisticated tests and entire test suites.

## Unit Test

Whenever possible, you should unit test your services. The simpler, better separated, and better defined your service dependencies are, the easier it is to test them. In this case, you can write simple tests like the following:

```typescript
export class MyService {
    helloWorld() {
        return 'hello world';
    }
}
```

```typescript
//
import { MyService } from './my-service.ts';

test('hello world', () => {
    const myService = new MyService();
    expect(myService.helloWorld()).toBe('hello world');
});
```

## Integration tests

It's not always possible to write unit tests, nor is it always the most efficient way to cover business-critical code and behavior. Especially if your architecture is very complex, it is beneficial to be able to easily perform end-to-end integration tests.

As you have already learned in the Dependency Injection chapter, the Dependency Injection Container is the heart of Deepkit. This is where all services are built and run. Your application defines services (providers), controllers, listeners, and imports. For integration testing, you don't necessarily want to have all services available in a test case, but you usually want to have a stripped down version of the application available to test the critical areas.

```typescript
import { createTestingApp } from '@deepkit/framework';
import { http, HttpRequest } from '@deepkit/http';

test('http controller', async () => {
    class MyController {

        @http.GET()
        hello(@http.query() text: string) {
            return 'hello ' + text;
        }
    }

    const testing = createTestingApp({ controllers: [MyController] });
    await testing.startServer();

    const response = await testing.request(HttpRequest.GET('/').query({text: 'world'}));

    expect(response.getHeader('content-type')).toBe('text/plain; charset=utf-8');
    expect(response.body.toString()).toBe('hello world');
});
```

```typescript
import { createTestingApp } from '@deepkit/framework';

test('service', async () => {
    class MyService {
        helloWorld() {
            return 'hello world';
        }
    }

    const testing = createTestingApp({ providers: [MyService] });

    //access the dependency injection container and instantiate MyService
    const myService = testing.app.get(MyService);

    expect(myService.helloWorld()).toBe('hello world');
});
```

If you have divided your application into several modules, you can test them more easily. For example, suppose you have created an `AppCoreModule` and want to test some services.

```typescript
class Config {
    items: number = 10;
}

export class MyService {
    constructor(protected items: Config['items']) {

    }

    doIt(): boolean {
        //do something
        return true;
    }
}

export AppCoreModule = new AppModule({}, {
    config: config,
    provides: [MyService]
}, 'core');
```

You use your module as follows:

```typescript
import { AppCoreModule } from './app-core.ts';

new App({
    imports: [new AppCoreModule]
}).run();
```

And test it without booting the entire application server.

```typescript
import { createTestingApp } from '@deepkit/framework';
import { AppCoreModule, MyService } from './app-core.ts';

test('service simple', async () => {
    const testing = createTestingApp({ imports: [new AppCoreModule] });

    const myService = testing.app.get(MyService);
    expect(myService.doIt()).toBe(true);
});

test('service simple big', async () => {
    // you change configurations of your module for specific test scenarios
    const testing = createTestingApp({
        imports: [new AppCoreModule({items: 100})]
    });

    const myService = testing.app.get(MyService);
    expect(myService.doIt()).toBe(true);
});
```

---

Source: https://deepkit.io/en/documentation/framework/deployment

# Deployment

In this chapter, you will learn how to compile your application in JavaScript, configure it for your production environment, and deploy it using Docker.

## Compile TypeScript

Suppose you have an application like this in an `app.ts` file:

```typescript
#!/usr/bin/env ts-node-script
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { http } from '@deepkit/http';

class Config {
    title: string = 'DEV my Page';
}

class MyWebsite {
    constructor(protected title: Config['title']) {
    }

    @http.GET()
    helloWorld() {
        return 'Hello from ' + this.title;
    }
}

new App({
    config: Config,
    controllers: [MyWebsite],
    imports: [new FrameworkModule]
})
    .loadConfigFromEnv()
    .run();
```

If you use `ts-node app.ts server:start`, you will see that everything works correctly. In a production environment, you would not typically start the server with `ts-node`. You would compile it into JavaScript and then use the node. To do this, you must have a correct `tsconfig.json` with the correct configuration options. In the "First Application" section, your `tsconfig.json` is configured to output JavaScript to the `.dist` folder. We assume that you have configured it that way as well.

If all compiler settings are correct and your `outDir` points to a folder like `dist`, then as soon as you run the `tsc` command in your project, all your linked files in the files in the `tsconfig.json` will be compiled to JavaScript. It is enough to specify your entry files in this list. All imported files are also compiled automatically and do not need to be explicitly added to `tsconfig.json`. `tsc` is part of Typescript when you install `npm install typescript`.

```sh
$ ./node_modules/.bin/tsc
```

The TypeScript compiler does not output anything if it was successful. You can now check the output of `dist`.

```sh
$ tree dist
dist
└── app.js
```

You can see that there is only one file. You can run it via `node distapp.js` and get the same functionality as with `ts-node app.ts`.

For a deployment, it is important that the TypeScript files are compiled correctly and everything works directly through Node. You could now simply move your `dist` folder including your `node_modules` and run `node distapp.js server:start` and your app is successfully deployed. However, you would use other solutions like Docker to package your app correctly.

## Configuration

In a production environment, you would not bind the server to `localhost`, but most likely to all devices via `0.0.0.0`. If you are not behind a reverse proxy, you would also set the port to 80. To configure these two settings, you need to customize the `FrameworkModule`. The two options we are interested in are `host` and `port`. In order for them to be configured externally via environment variables or via .dotenv files, we must first allow this. Fortunately, our code above has already done this with the `loadConfigFromEnv()` method.

Please refer to the [Configuration](https://deepkit.io/en/documentation/app/configuration.md) chapter to learn more about how to set the application configuration options.

To see what configuration options are available and what value they have, you can use the `ts-node app.ts app:config` command. You can also see them in the Framework Debugger.

### SSL

It is recommended (and sometimes required) to run your application over HTTPS with SSL. There are several options for configuring SSL. To enable SSL, use
`framework.ssl` and configure its parameters with the following options.

|===
|Name|Type|Description

|framework.ssl|boolean|Enables HTTPS server when true
|framework.httpsPort|number?|If httpsPort and ssl is defined, then the https server is started additional to the http server.
|framework.sslKey|string?|A file path to a ssl key file for https
|framework.sslCertificate|string?|A file path to a certificate file for https
|framework.sslCa|string?|A file path to a ca file for https
|framework.sslCrl|string?|A file path to a crl file for https
|framework.sslOptions|object?|Same interface as tls.SecureContextOptions & tls.TlsOptions.
|===

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';

// your config and http controller here

new App({
    config: Config,
    controllers: [MyWebsite],
    imports: [
        new FrameworkModule({
            ssl: true,
            selfSigned: true,
            sslKey: __dirname + 'path/ssl.key',
            sslCertificate: __dirname + 'path/ssl.cert',
            sslCA: __dirname + 'path/ssl.ca',
        })
    ]
})
    .run();
```

### Local SSL

In the local development environment, you can enable self-signed HTTPs with the `framework.selfSigned` option.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';

// your config and http controller here

new App({
    config: config,
    controllers: [MyWebsite],
    imports: [
        new FrameworkModule({
            ssl: true,
            selfSigned: true,
        })
    ]
})
    .run();
```

```sh
$ ts-node app.ts server:start
2021-06-13T18:04:01.563Z [LOG] Start HTTP server, using 1 workers.
2021-06-13T18:04:01.598Z [LOG] Self signed certificate for localhost created at var/self-signed-localhost.cert
2021-06-13T18:04:01.598Z [LOG] Tip: If you want to open this server via chrome for localhost, use chrome://flags/#allow-insecure-localhost
2021-06-13T18:04:01.606Z [LOG] HTTP MyWebsite
2021-06-13T18:04:01.606Z [LOG]     GET / helloWorld
2021-06-13T18:04:01.606Z [LOG] HTTPS listening at https://localhost:8080/
```

If you start this server now, your HTTP server is available as HTTPS at `https:localhost:8080`. In Chrome, you now get the error message "NET::ERR_CERT_INVALID" when you open this URL because self-signed certificates are considered a security risk: `chrome:flagsallow-insecure-localhost`.

---

Source: https://deepkit.io/en/documentation/framework/public

# Public Directory

The `FrameworkModule` provides a way to serve static files such as images, PDFs, binaries, etc. over HTTP. The `publicDir` configuration option lets you specify which folder to use as the default entry point for requests that do not lead to an HTTP controller route. By default, this behavior is disabled (empty value).

To enable the provision of public files, set `publicDir` to a folder of your choice. Normally you would choose a name like `publicDir` to make things obvious.

```
.
├── app.ts
└── publicDir
    └── logo.jpg
```

To change the `publicDir` option, you can change the first argument of `FrameworkModule`.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';

// your config and http controller here

new App({
    config: config,
    controllers: [MyWebsite],
    imports: [
        new FrameworkModule({
            publicDir: 'publicDir'
        })
    ]
})
    .run();
```

All files within this configured folder are now accessible via HTTP. For example, if you open `http:localhost:8080/logo.jpg`, you will see the image `logo.jpg` in the `publicDir` directory.

---

Source: https://deepkit.io/en/documentation/runtime-types

# Runtime Types

Runtime type information in TypeScript unlocks new workflows and features that were previously unavailable or required workarounds. Modern development processes rely heavily on declaring types and schemas for tools like GraphQL, validators, ORMs, and encoders such as ProtoBuf. These tools may require developers to learn new languages specific to their use case, like ProtoBuf and GraphQL having their own declaration language, or validators using their own schema APIs or JSON-Schema.

TypeScript has become powerful enough to describe complex structures and even replace declaration formats like GraphQL, ProtoBuf, and JSON-Schema entirely. With a runtime type system, it's possible to cover the use cases of these tools without any code generators or runtime JavaScript type declaration libraries like "Zod". The Deepkit library aims to provide runtime type information and make it easier to develop efficient and compatible solutions.

Deepkit is built upon the ability to read type information at runtime, using as much TypeScript type information as possible for efficiency. The runtime type system allows reading and computing dynamic types, such as class properties, function parameters, and return types. Deepkit hooks into TypeScript's compilation process to ensure that all type information is embedded into the generated JavaScript using a [custom bytecode and virtual machine](https://github.com/microsoft/TypeScript/issues/47658), enabling developers to access type information programmatically.

With Deepkit, developers can use their existing TypeScript types for validation, serialisation and more at runtime, simplifying their development process and making their work more efficient.

---

Source: https://deepkit.io/en/documentation/runtime-types/getting-started

# Getting started

To install Deepkit's runtime type system two packages are needed: The Deepkit Type Compiler and the Deepkit Type package itself. The type compiler is a TypeScript transformer that generates runtime type information from TypeScript types. The type package contains the runtime virtual machine and type annotations as well as many useful functions for working with types.


## Installation 

```sh
npm install --save @deepkit/type
npm install --save-dev @deepkit/type-compiler typescript ts-node
```

Runtime type information is not generated by default. It must be set `"reflection": true` in the `tsconfig.json` file to enable it. 

If decorators are to be used, `"experimentalDecorators": true` must be enabled in `tsconfig.json`. This is not strictly necessary to work with `@deepkit/type`, but necessary for certain functions of other Deepkit libraries and in Deepkit Framework.

_File: tsconfig.json_

```json
{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "es6",
    "moduleResolution": "node",
    "experimentalDecorators": true
  },
  "reflection": true
}
```

Write your first code with runtime type information:

_File: app.ts_

```typescript
import { cast, MinLength, ReflectionClass } from '@deepkit/type';

interface User {
    username: string & MinLength<3>;
    birthDate?: Date;
}

const user = cast<User>({
    username: 'Peter',
    birthDate: '2010-10-10T00:00:00Z'
});
console.log(user);

const reflection = ReflectionClass.from<User>();
console.log(reflection.getProperty('username').type);
```

And run it with `ts-node`:

```sh
./node_modules/.bin/ts-node app.ts
```

## Interactive Example

Here is a codesandbox example: https://codesandbox.io/p/sandbox/deepkit-runtime-types-fjmc2f?file=index.ts

## Type compiler

TypeScript itself does not allow to configure the type compiler via a `tsconfig.json`. It is necessary to either use the TypeScript compiler API directly or a build system like Webpack with _ts-loader_. To save this inconvenient way for Deepkit users, the Deepkit type compiler automatically installs itself in `node_modules/typescript` once `@deepkit/type-compiler` is installed (this is done via NPM install hooks).
This makes it possible for all build tools that access the locally installed TypeScript (the one in `node_modules/typescript`) to automatically have the type compiler enabled. This makes _tsc_, Angular, webpack, _ts-node_, and some other tools automatically work with the deepkit type compiler.

If the type compiler could not be successfully installed automatically (for example because NPM install hooks are disabled), this can be done manually with the following command:

```sh
node_modules/.bin/deepkit-type-install
```

Note that `deepkit-type-install` must be run if the local typescript version has been updated (for example, if the typescript version in package.json has changed and `npm install` is run).

## Webpack

If you want to use the type compiler in a webpack build, you can do so with the `ts-loader` package (or any other typescript loader that supports transformer registration).

_File: webpack.config.js_

```javascript
const typeCompiler = require('@deepkit/type-compiler');

module.exports = {
  entry: './app.ts',
  module: {
    rules: [
      {
        test: /\.tsx?$/,
          use: {
            loader: 'ts-loader',
            options: {
              //this enables @deepkit/type's type compiler
              getCustomTransformers: (program, getProgram) => ({
                before: [typeCompiler.transformer],
                afterDeclarations: [typeCompiler.declarationTransformer],
              }),
            }
          },
          exclude: /node_modules/,
       },
    ],
  },
}
```

---

Source: https://deepkit.io/en/documentation/runtime-types/types

# Type Annotations

Type annotations are normal TypeScript types that contain meta-information that can be read and change the behavior of various functions at runtime. Deepkit already provides some type annotations that cover many use cases. For example, a class property can be marked as primary key, reference, or index. The database library can use this information at runtime to create the correct SQL queries without prior code generation.

Validator constraints such as `MaxLength`, `Maximum`, or `Positive` can also be added to any type. It is also possible to tell the serializer how to serialize or deserialize a particular value. In addition, it is possible to create completely custom type annotations and read them at runtime, in order to use the type system at runtime in a very individual way.

Deepkit comes with a whole set of type annotations, all of which can be used directly from `@deepkit/type`. They are designed not to come from multiple libraries, so as not to tie code directly to a particular library such as Deepkit RPC or Deepkit Database. This allows easier reuse of types, even in the frontend, although database type annotations are used for example.

Following is a list of existing type annotations. The validator and serializer of `@deepkit/type` and `@deepkit/bson` and Deepkit Database of `@deepkit/orm` used this information differently. See the corresponding chapters to learn more about this.

## Integer/Float

Integer and floats are defined as a base as `number` and has several sub-variants:

| Type    | Description                                                                                                                                                                                                           |
|---------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| integer | An integer of arbitrary size.                                                                                                                                                                                         |
| int8    | An integer between -128 and 127.                                                                                                                                                                                      |
| uint8   | An integer between 0 and 255.                                                                                                                                                                                         |
| int16   | An integer between -32768 and 32767.                                                                                                                                                                                  |
| uint16  | An integer between 0 and 65535.                                                                                                                                                                                       |
| int32   | An integer between -2147483648 and 2147483647.                                                                                                                                                                        |
| uint32  | An integer between 0 and 4294967295.                                                                                                                                                                                  |
| float   | Same as number, but might have different meaning in database context.                                                                                                                                                 |
| float32 | A float between -3.40282347e+38 and 3.40282347e+38. Note that JavaScript is not able to check correctly the range due to precision issues, but the information might be handy for the database or binary serializers. |
| float64 | Same as number, but might have different meaning in database context.                                                                                                                                                 |

```typescript
import { integer } from '@deepkit/type';

interface User {
    id: integer;
}
```

Here the `id` of the user is a number at runtime, but is interpreted as an integer in the validation and serialization.
This means that here, for example, no floats may be used in validation and the serializer automatically converts floats into integers.

```typescript
import { is, integer } from '@deepkit/type';

is<integer>(12); //true
is<integer>(12.5); //false
```

The subtypes can be used in the same way and are useful if a specific range of numbers is to be allowed.

```typescript
import { is, int8 } from '@deepkit/type';

is<int8>(-5); //true
is<int8>(5); //true
is<int8>(-200); //false
is<int8>(2500); //false
```

```typescript
import { is, float, float32, float64 } from '@deepkit/type';
is<float>(12.5); //true
is<float32>(12.5); //true
is<float64>(12.5); //true
````

## UUID

UUID v4 is usually stored as a binary in the database and as a string in JSON.

```typescript
import { is, UUID } from '@deepkit/type';

is<UUID>('f897399a-9f23-49ac-827d-c16f8e4810a0'); //true
is<UUID>('asd'); //false
```

## MongoID

Marks this field as ObjectId for MongoDB. Resolves as a string. Is stored in the MongoDB as binary.

```typescript
import { MongoId, serialize, is } from '@deepkit/type';

serialize<MongoId>('507f1f77bcf86cd799439011'); //507f1f77bcf86cd799439011
is<MongoId>('507f1f77bcf86cd799439011'); //true
is<MongoId>('507f1f77bcf86cd799439011'); //false

class User {
    id: MongoId = ''; //will automatically set in Deepkit ORM once user is inserted
}
```

## Bigint

Per default the normal bigint type serializes as number in JSON (and long in BSON). This has however limitation in what is possible to save since bigint in JavaScript has an unlimited potential size, where numbers in JavaScript and long in BSON are limited. To bypass this limitation the types `BinaryBigInt` and `SignedBinaryBigInt` are available.

`BinaryBigInt` is the same as bigint but serializes to unsigned binary with unlimited size (instead of 8 bytes in most databases) in databases and string in JSON. Negative values will be converted to positive (`abs(x)`).

```typescript
import { BinaryBigInt } from '@deepkit/type';

interface User {
    id: BinaryBigInt;
}

const user: User = { id: 24n };

serialize<User>({ id: 24n }); //{id: '24'}

serialize<BinaryBigInt>(24); //'24'
serialize<BinaryBigInt>(-24); //'0'
```

Deepkit ORM stores BinaryBigInt as a binary field.

`SignedBinaryBigInt` is the same as `BinaryBigInt` but is able to store negative values as well. Deepkit ORM stores `SignedBinaryBigInt` as binary. The binary has an additional leading sign byte and is represented as an uint: 255 for negative, 0 for zero, or 1 for positive.

```typescript
import { SignedBinaryBigInt } from '@deepkit/type';

interface User {
    id: SignedBinaryBigInt;
}
```

## MapName

To change the name of a property in the serialization.

```typescript
import { serialize, deserialize, MapName } from '@deepkit/type';

interface User {
    firstName: string & MapName<'first_name'>;
}

serialize<User>({ firstName: 'Peter' }) // {first_name: 'Peter'}
deserialize<User>({ first_name: 'Peter' }) // {firstName: 'Peter'}
```

## Group

Properties can be grouped together. For serialization you can for example exclude a group from serialization. See the chapter Serialization for more information.

```typescript
import { serialize } from '@deepkit/type';

interface Model {
    username: string;
    password: string & Group<'secret'>
}

serialize<Model>(
    { username: 'Peter', password: 'nope' },
    { groupsExclude: ['secret'] }
); //{username: 'Peter'}
```

## Data

Each property can add additional meta-data that can be read via the Reflection API. See [Runtime Types Reflection](https://deepkit.io/en/documentation/runtime-types/reflection.md) for more information.

```typescript
import { ReflectionClass } from '@deepkit/type';

interface Model {
    username: string;
    title: string & Data<'key', 'value'>
}

const reflection = ReflectionClass.from<Model>();
reflection.getProperty('title').getData()['key']; //value;
```

## Excluded

Each property can be excluded from the serialization process for a specific target.

```typescript
import { serialize, deserialize, Excluded } from '@deepkit/type';

interface Auth {
    title: string;
    password: string & Excluded<'json'>
}

const item = deserialize<Auth>({ title: 'Peter', password: 'secret' });

item.password; //undefined, since deserialize's default serializer is called `json`

item.password = 'secret';

const json = serialize<Auth>(item);
json.password; //again undefined, since serialize's serializer is called `json`
```

## Embedded

Marks the field as an embedded type.

```typescript
import { PrimaryKey, Embedded, serialize, deserialize } from '@deepkit/type';

interface Address {
    street: string;
    postalCode: string;
    city: string;
    country: string;
}

interface User {
    id: number & PrimaryKey;
    address: Embedded<Address>;
}

const user: User
{
    id: 12,
        address
:
    {
        street: 'abc', postalCode
    :
        '1234', city
    :
        'Hamburg', country
    :
        'Germany'
    }
}
;

serialize<User>(user);
{
    id: 12,
        address_street
:
    'abc',
        address_postalCode
:
    '1234',
        address_city
:
    'Hamburg',
        address_country
:
    'Germany'
}

//for deserialize you have to provide the embedded structure
deserialize<User>({
    id: 12,
    address_street: 'abc',
    //...
});
```

It's possible to change the prefix (which is per default the property name).

```typescript
interface User {
    id: number & PrimaryKey;
    address: Embedded<Address, { prefix: 'addr_' }>;
}

serialize<User>(user);
{
    id: 12,
        addr_street
:
    'abc',
        addr_postalCode
:
    '1234',
}

//or remove it entirely
interface User {
    id: number & PrimaryKey;
    address: Embedded<Address, { prefix: '' }>;
}

serialize<User>(user);
{
    id: 12,
        street
:
    'abc',
        postalCode
:
    '1234',
}
```

## Entity

To annotate interfaces with entity information. Only used in the database context.

```typescript
import { Entity, PrimaryKey } from '@deepkit/type';

interface User extends Entity<{ name: 'user', collection: 'users'> {
    id: number & PrimaryKey;
    username: string;
}
```

## PrimaryKey

Marks the field as primary key. Only used in the database context.

```typescript
import { PrimaryKey } from '@deepkit/type';

interface User {
    id: number & PrimaryKey;
}
```

## AutoIncrement

Marks the field as auto increment. Only used in the database context.
Usually together with `PrimaryKey`.

```typescript
import { AutoIncrement } from '@deepkit/type';

interface User {
    id: number & PrimaryKey & AutoIncrement;
}
```

## Reference

Marks the field as reference (foreign key). Only used in the database context.

```typescript
import { Reference } from '@deepkit/type';

interface User {
    id: number & PrimaryKey;
    group: number & Reference<Group>;
}

interface Group {
    id: number & PrimaryKey;
}
```

In this example `User.group` is an owning reference also known as foreign key in SQL. This means that the `User` table has a column `group` that references the `Group` table. The `Group` table is the target table of the reference.

## BackReference

Marks the field as back reference. Only used in the database context.

```typescript

interface User {
    id: number & PrimaryKey;
    group: number & Reference<Group>;
}

interface Group {
    id: number & PrimaryKey;
    users: User[] & BackReference;
}
```

In this example `Group.users` is a back reference. This means that the `User` table has a column `group` that references the `Group` table.
The `Group` has a virtual property `users` that is automatically populated with all users that have the same `group` id as the `Group` id once a database query
with joins is executed. The property `users` is not stored in the database.

## Index

Marks the field as index. Only used in the database context.

```typescript
import { Index } from '@deepkit/type';

interface User {
    id: number & PrimaryKey;
    username: string & Index;
}
```

## Unique

Marks the field as unique. Only used in the database context.

```typescript
import { Unique } from '@deepkit/type';

interface User {
    id: number & PrimaryKey;
    username: string & Unique;
}
```

## DatabaseField

With `DatabaseField` you can define the database specific options like the real database column type, and the default value, etc.

```typescript
import { DatabaseField } from '@deepkit/type';

interface User {
    id: number & PrimaryKey;
    username: string & DatabaseField<{ type: 'varchar(255)' }>;
}
```

## Validation

TODO

See [Validation Constraint Types](https://deepkit.io/en/documentation/runtime-types/validation.md#validation-constraint-types).

## InlineRuntimeType

To inline a runtime type. Only used in advanced cases.

```typescript
import { InlineRuntimeType, ReflectionKind, Type } from '@deepkit/type';

const type: Type = { kind: ReflectionKind.string };

type Query = {
    field: InlineRuntimeType<typeof type>;
}

const resolved = typeOf<Query>(); // { field: string }
```

In TypeScript the type `Query` is `{ field: any }`, but in runtime it's `{ field: string }`.

This is useful if you build a highly customizable system where you accept runtime types, and you reuse them in various other cases.

## ResetAnnotation

To reset all annotations of a property. Only used in advanced cases.

```typescript
import { ResetAnnotation } from '@deepkit/type';

interface User {
    id: number & PrimaryKey;
}

interface UserCreationPayload {
    id: User['id'] & ResetAnnotation<'primaryKey'>;
}
```

### Custom Type Annotations

You can define your own type annotations.

```typescript
type MyAnnotation = { __meta?: ['myAnnotation'] };
```

By convention, a type annotation is defined to be an object literal with a single optional property `__meta` that has a tuple as its type. The first entry in this tuple is its unique name and all subsequent tuple entries are arbitrary options. This allows a type annotation to be equipped with additional options.

```typescript
type AnnotationOption<T extends { title: string }> = { __meta?: ['myAnnotation', T] };
```

The type annotation is used with the intersection operator `&`. Any number of type annotations can be used on one type.

```typescript
type Username = string & MyAnnotation;
type Title = string & MyAnnotation & AnnotationOption<{ title: 'Hello' }>;
```

The type annotations can be read out via the type objects of `typeOf<T>()` and `typeAnnotation`:

```typescript
import { typeOf, typeAnnotation } from '@deepkit/type';

const type = typeOf<Username>();
const annotation = typeAnnotation.getForName(type, 'myAnnotation'); //[]
```

The result in `annotation` is either an array with options if the type annotation `myAnnotation` was used or `undefined` if not. If the type annotation has additional options as seen in `AnnotationOption`, the passed values can be found in the array.
Already supplied type annotations like `MapName`, `Group`, `Data`, etc have their own annotation object:

```typescript
import { typeOf, Group, groupAnnotation } from '@deepkit/type';

type Username = string & Group<'a'> & Group<'b'>;

const type = typeOf<Username>();
groupAnnotation.getAnnotations(type); //['a', 'b']
```

See [Runtime Types Reflection](https://deepkit.io/en/documentation/runtime-types/reflection.md) to learn more.

---

Source: https://deepkit.io/en/documentation/runtime-types/reflection

# Reflection

To work directly with the type information itself, there are two basic variants: Type objects and Reflection classes. Type objects are regular JS objects returned by `typeOf<T>()`. Reflection classes are discussed below.


The function `typeOf` works for all types, including interfaces, object literals, classes, functions, and type aliases. It returns a type object that contains all the information about the type. You can pass any type as a type argument, including generics.

```typescript
import { typeOf } from '@deepkit/type';

typeOf<string>(); //{kind: 5}
typeOf<number>(); //{kind: 6}

typeOf<{id: number}>(); //{kind: 4, types: [{kind: 6, name: 'id'}]}

class User {
    id: number
}

typeOf<User>(); //{kind: 4, types: [...]}

function test(id: number): string {}

typeOf<typeof test>(); //{kind: 12, parameters: [...], return: {kind: 5}}
```

The type object is a simple object literal that contains a `kind` property that indicates the type of the type object. The `kind` property is a number and gets its meaning from the enum `ReflectionKind`. `ReflectionKind` is defined in the `@deepkit/type` package as follows:

```typescript
enum ReflectionKind {
  never,    //0
  any,     //1
  unknown, //2
  void,    //3
  object,  //4
  string,  //5
  number,  //6
  boolean, //7
  symbol,  //8
  bigint,  //9
  null,    //10
  undefined, //11

  //... and even more
}
```

There are a number of possible type objects that can be returned. The simplest ones are `never`, `any`, `unknown`, `void, null,` and `undefined`, which are represented as follows:

```typescript
{kind: 0}; //never
{kind: 1}; //any
{kind: 2}; //unknown
{kind: 3}; //void
{kind: 10}; //null
{kind: 11}; //undefined
```

For example, number 0 is the first entry of the `ReflectionKind` enum, in this case `never`, number 1 is the second entry, here `any`, and so on. Accordingly, primitive types like `string`, `number`, `boolean` are represented as follows:

```typescript
typeOf<string>(); //{kind: 5}
typeOf<number>(); //{kind: 6}
typeOf<boolean>(); //{kind: 7}
```

These rather simple types have no further information at the type object, because they were passed directly as type argument to `typeOf`. However, if types are passed via type aliases, additional information can be found at the type object.

```typescript
type Title = string;

typeOf<Title>(); //{kind: 5, typeName: 'Title'}
```

In this case, the name of the type alias 'Title' is also available. If a type alias is a generic, the types passed will also be available at the type object.

```typescript
type Title<T> = T extends true ? string : number;

typeOf<Title<true>>();
{kind: 5, typeName: 'Title', typeArguments: [{kind: 7}]}
```

If the type passed is the result of an index access operator, the container and the index type are present:

```typescript
interface User {
  id: number;
  username: string;
}

typeOf<User['username']>();
{kind: 5, indexAccessOrigin: {
    container: {kind: Reflection.objectLiteral, types: [...]},
    Index: {kind: Reflection.literal, literal: 'username'}
}}
```

Interfaces and object literals are both output as Reflection.objectLiteral and contain the properties and methods in the `types` array.

```typescript
interface User {
  id: number;
  username: string;
  login(password: string): void;
}

typeOf<User>();
{
  kind: Reflection.objectLiteral,
  types: [
    {kind: Reflection.propertySignature, name: 'id', type: {kind: 6}},
    {kind: Reflection.propertySignature, name: 'username',
     type: {kind: 5}},
    {kind: Reflection.methodSignature, name: 'login', parameters: [
      {kind: Reflection.parameter, name: 'password', type: {kind: 5}}
    ], return: {kind: 3}},
  ]
}

type User  = {
  id: number;
  username: string;
  login(password: string): void;
}
typeOf<User>(); //returns the same object as above
```

Index signatures are also in the `types` array.

```typescript
interface BagOfNumbers {
    [name: string]: number;
}


typeOf<BagOfNumbers>;
{
  kind: Reflection.objectLiteral,
  types: [
    {
      kind: Reflection.indexSignature,
      index: {kind: 5}, //string
      type: {kind: 6}, //number
    }
  ]
}

type BagOfNumbers  = {
    [name: string]: number;
}
typeOf<BagOfNumbers>(); //returns the same object as above
```

Classes are similar to object literals and also have their properties and methods under a `types` array in addition to `classType` which is a reference to the class itself.

```typescript
class User {
  id: number = 0;
  username: string = '';
  login(password: string): void {
     //do nothing
  }
}

typeOf<User>();
{
  kind: Reflection.class,
  classType: User,
  types: [
    {kind: Reflection.property, name: 'id', type: {kind: 6}},
    {kind: Reflection.property, name: 'username',
     type: {kind: 5}},
    {kind: Reflection.method, name: 'login', parameters: [
      {kind: Reflection.parameter, name: 'password', type: {kind: 5}}
    ], return: {kind: 3}},
  ]
}
```

Note that the type of Reflection.propertySignature has changed to Reflection.property and Reflection.methodSignature has changed to Reflection.method. Since properties and methods on classes have additional attributes, this information can also be retrieved. The latter additionally include `visibility`, `abstract`, and `default`.
Type objects of classes contain only the properties and methods of the class itself and not of super-classes. This is contrary to type objects of interfacesobject-literals, which have all property signatures and method signatures of all parents resolved into `types`. To resolve the property and methods of the super-classes, either ReflectionClass and its `ReflectionClass.getProperties()` (see following sections) or `resolveTypeMembers()` of `@deepkit/type` can be used.

There is a whole plethora of type objects. For example for literal, template literals, promise, enum, union, array, tuple, and many more. To find out which ones all exist and what information is available, it is recommended to import `Type` from `@deepkit/type`. It is a `union` with all possible subtypes like TypeAny, TypeUnknonwn, TypeVoid, TypeString, TypeNumber, TypeObjectLiteral, TypeArray, TypeClass, and many more. There you can find the exact structure.

## Type Cache

Type objects are cached for type aliases, functions, and classes as soon as no generic argument is passed. This means that a call to `typeOf<MyClass>()` always returns the same object.

```typescript
type MyType = string;

typeOf<MyType>() === typeOf<MyType>(); //true
```

However, as soon as a generic type is used, new objects are always created, even if the type passed is always the same. This is because an infinite number of combinations are theoretically possible and such a cache would effectively be a memory leak.

```typescript
type MyType<T> = T;

typeOf<MyType<string>>() === typeOf<MyType<string>>();
//false
```

However, as soon as a type is instantiated multiple times in a recursive type, it is cached. However, the duration of the cache is limited only to the moment the type is computed and does not exist thereafter. Also, although the Type object is cached, a new reference is returned and is not the exact same object.

```typescript
type MyType<T> = T;
type Object = {
   a: MyType<string>;
   b: MyType<string>;
};

typeOf<Object>();
```

`MyType<string>` is cached as long as `Object` is computed. The PropertySignature of `a` and `b` thus have the same `type` from the cache, but are not the same Type object.

All non-root Type objects have a parent property, which usually points to the enclosing parent. This is valuable, for example, to find out whether a Type is part of a union or not.

```typescript
type ID = string | number;

typeOf<ID>();
*Ref 1* {
  kind: ReflectionKind.union,
  types: [
    {kind: ReflectionKind.string, parent: *Ref 1* } }
    {kind: ReflectionKind.number, parent: *Ref 1* }
  ]
}
```

'Ref 1' points to the actual union type object.

For cached Type objects as exemplified above, the `parent` properties are not always the real parents. For example, for a class that is used multiple times, although immediate types in `types` (TypePropertySignature and TypeMethodSignature) point to the correct TypeClass, the `type` of these signature types point to the signature types of the TypeClass of the cached entry. This is important to know so as not to infinitely read the parent structure, but only the immediate parent. The fact that the parent does not have infinite precision is due to performance reasons.

## JIT Cache

In the further course some functions and features are described, which are often based on the type objects. To implement some of them in a performant way, a JIT (just in time) cache per type object is needed. This can be provided via `getJitContainer(type)`. This function returns a simple object on which arbitrary data can be stored. As long as no reference to the object is held, it will be deleted automatically by the GC as soon as the Type object itself is also no longer referenced.


## Reflection Classes

In addition to the `typeOf<>()` function, there are various reflection classes that provide an OOP alternative to the Type objects. The reflection classes are only available for classes, InterfaceObject literals and functions and their direct sub-types (Properties, Methods, Parameters). All deeper types must be read again with the Type objects.

```typescript
import { ReflectionClass } from '@deepkit/type';

interface User {
    id: number;
    username: string;
}


const reflection = ReflectionClass.from<User>();

reflection.getProperties(); //[ReflectionProperty, ReflectionProperty]
reflection.getProperty('id'); //ReflectionProperty

reflection.getProperty('id').name; //'id'
reflection.getProperty('id').type; //{kind: ReflectionKind.number}
reflection.getProperty('id').isOptional(); //false
```


## Receive type information

In order to provide functions that operate on types, it can be useful to offer the user to pass a type manually. For example, in a validation function, it might be useful to provide the type to be requested as the first type argument and the data to be validated as the first function argument.

```typescript
validate<string>(1234);
```

In order for this function to get the type `string`, it must tell this to the type compiler.

```typescript
function validate<T>(data: any, type?: ReceiveType<T>): void;
```

`ReceiveType` with the reference to the first type arguments `T` signals the type compiler that each call to `validate` should put the type in second place (since `type` is declared in second place). To then read out the information at runtime, the `resolveReceiveType` function is used.

```typescript
import { resolveReceiveType, ReceiveType } from '@deepkit/type';

function validate<T>(data: any, type?: ReceiveType<T>): void {
    type = resolveReceiveType(type);
}
```

It is useful to assign the result to the same variable to avoid creating a new one unnecessarily. In `type` now either a type object is stored or an error is thrown, if for example no type argument was passed, Deepkit's type compiler was not installed correctly, or the emitting of type information is not activated (see the section Installation above).

---

Source: https://deepkit.io/en/documentation/runtime-types/serialization

# Serialisation

Serialization is the process of converting data types into a format suitable for transport or storage, for example. Deserialization is the process of undoing this. This is done loss-lessly, meaning that data can be converted to and from a serialization target without losing data type information or the data itself.

In JavaScript, serialization is usually between JavaScript objects and JSON. JSON supports only String, Number, Boolean, Objects, and Arrays. JavaScript, on the other hand, supports many other types such as BigInt, ArrayBuffer, typed arrays, Date, custom class instances, and many more. Now, to transmit JavaScript data to a server using JSON, you need a serialization process (on the client) and a deserialization process (on the server), or vice versa if the server sends data to the client as JSON. Using `JSON.parse` and `JSON.stringify` is often not sufficient for this, as it is not lossless.

This serialization process is absolutely necessary for non-trivial data, since JSON loses its information even for basic types like a date. A new Date is finally serialized as a string in JSON:

```typescript
const json = JSON.stringify(new Date);
//'"2022-05-13T20:48:51.025Z"
```

As you can see, the result of JSON.stringify is a JSON string. If you deserialize it again with JSON.parse, you will not get a date object, but a string.

```typescript
const value = JSON.parse('"2022-05-13T20:48:51.025Z"');
//"2022-05-13T20:48:51.025Z"
```

Although there are various workarounds to teach JSON.parse to deserialize Date objects, they are error-prone and poorly performing. To enable typesafe serialization and deserialization for this case and many other types, a serialization process is necessary.

There are four main functions available: `serialize`, `cast`, `deserialize` and `validatedDeserialize`. Under the hood of these functions, the globally available JSON serializer from `@deepkit/type` is used by default, but a custom serialization target can also be used.

Deepkit Type supports user-defined serialization targets, but already comes with a powerful JSON serialization target that serializes data as JSON objects and then can be correctly and safely converted as JSON using JSON.stringify. With `@deepkit/bson`, BSON can also be used as a serialization target. How to create a custom serialization target (for example for a database driver) can be learned in the Custom Serializer section.

Note that although serializers also validate data for compatibility, these validations are different from the validation in [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md). Only the `cast` function also calls the full validation process from the [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md) chapter after successful deserialization, and throws an error if the data is not valid.

Alternatively, `validatedDeserialize` can be used to validate after deserialization. Another alternative is to manually call the `validate` or `validates` functions on deserialized data from the `deserialize` function, see [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md).

All functions from serialization and validation throw a `ValidationError` from `@deepkit/type` on errors.

## Cast

The `cast` function expects as first type argument a TypeScript type, and as second argument the data to cast. The data is casted to the given type, and if successful, the data is returned. If the data is not compatible with the given type and can not be converted automatically, a `ValidationError` is thrown.

```typescript
import { cast } from '@deepkit/type';

cast<string>(123); //'123'
cast<number>('123'); //123
cast<number>('asdasd'); // throws ValidationError

cast<string | number>(123); //123
```

```typescript
class MyModel {
    id: number = 0;
    created: Date = new Date;

    constructor(public name: string) {
    }
}

const myModel = cast<MyModel>({
    id: 5,
    created: 'Sat Oct 13 2018 14:17:35 GMT+0200',
    name: 'Peter',
});
```

The `deserialize` function is similar to `cast`, but does not throw an error if the data is not compatible with the given type. Instead, the data is converted as far as possible and the result is returned. If the data is not compatible with the given type, the data is returned as it is.

## Serialization

```typescript
import { serialize } from '@deepkit/type';

class MyModel {
    id: number = 0;
    created: Date = new Date;

    constructor(public name: string) {
    }
}

const model = new MyModel('Peter');

const jsonObject = serialize<MyModel>(model);
//{
//  id: 0,
//  created: '2021-06-10T15:07:24.292Z',
//  name: 'Peter'
//}
const json = JSON.stringify(jsonObject);
```


The function `serialize` converts the passed data by default with the JSON serializer into a JSON object, that is: String, Number, Boolean, Object, or Array. The result of this can then be safely converted to a JSON using `JSON.stringify`.

## Deserialiazation

The function `deserialize` converts the passed data per default with the JSON serializer into the corresponding specified types. The JSON serializer expects a JSON object, i.e.: string, number, boolean, object, or array. This is usually obtained from a `JSON.parse` call.

```typescript
import { deserialize } from '@deepkit/type';

class MyModel {
    id: number = 0;
    created: Date = new Date;

    constructor(public name: string) {
    }
}

const myModel = deserialize<MyModel>({
    id: 5,
    created: 'Sat Oct 13 2018 14:17:35 GMT+0200',
    name: 'Peter',
});

//from JSON
const json = '{"id": 5, "created": "Sat Oct 13 2018 14:17:35 GMT+0200", "name": "Peter"}';
const myModel = deserialize<MyModel>(JSON.parse(json));
```

If the correct data type is already passed (for example, a Date object in the case of `created`), then this is taken as it is.

Not only a class, but any TypeScript type can be specified as the first type argument. So even primitives or very complex types can be passed:

```typescript
deserialize<Date>('Sat Oct 13 2018 14:17:35 GMT+0200');
deserialize<string | number>(23);
```

<a name="loosely-convertion"></a>
### Soft Type Conversion

In the deserialization process a soft type conversion is implemented. This means that String and Number for String types or a Number for a String type can be accepted and converted automatically. This is useful, for example, when data is accepted via a URL and passed to the deserializer. Since the URL is always a string, Deepkit Type still tries to resolve the types for Number and Boolean.

```typescript
deserialize<boolean>('false')); //false
deserialize<boolean>('0')); //false
deserialize<boolean>('1')); //true

deserialize<number>('1')); //1

deserialize<string>(1)); //'1'
```

The following soft type conversions are built into the JSON serializer:

* *number|bigint*: Number or Bigint accept String, Number, and BigInt. `parseFloat` or `BigInt(x)` are used in case of a necessary conversion.
* *boolean*: Boolean accepts Number and String. 0, '0', 'false' is interpreted as `false`. 1, '1', 'true' is interpreted as `true`.
* *string*: String accepts Number, String, Boolean, and many more. All non-string values are automatically converted with `String(x)`.

The soft conversion can also be deactivated:

```typescript
const result = deserialize(data, {loosely: false});
```

In the case of invalid data, no attempt is made to convert it and instead an error message is thrown.

---

Source: https://deepkit.io/en/documentation/runtime-types/validation

# Validation

Validation is the systematic process of verifying data for accuracy and integrity. This not only involves checking if the data type aligns with the expected type, but also whether any additional predefined constraints are satisfied.

Validation becomes paramount when dealing with data from uncertain or untrusted sources. An "uncertain" source is one where the types or contents of the data are unpredictable, potentially taking any value during runtime. Typical examples include user inputs, data from HTTP requests (like query parameters or the body), CLI arguments, or files that are read into a program. Such data is inherently risky as incorrect types or values can cause program failures, or even introduce security vulnerabilities.

For instance, if a variable is expected to store a number, validating to ensure that it actually contains a numeric value is crucial. A mismatch could lead to unexpected crashes or security breaches.

When designing an HTTP route controller for example, one must prioritize the validation of all user inputs, be it through query parameters, the request body, or other means. Particularly in environments utilizing TypeScript, it's vital to steer clear of type casts. These casts can be misleading and introduce fundamental security risks.

```typescript
app.post('/user', function(request) {
    const limit = request.body.limit as number;
});
```

A frequently encountered error in coding involves type casts that don't offer runtime security. For instance, if you type cast a variable as a number but a user inputs a string, the program is misled to operate as if the string is a number. Such oversights can cause system crashes or pose serious security threats. To mitigate these risks, developers can leverage validators and type guards. Additionally, serializers can play a role in converting variables, like converting 'limit' to a number. Further insights on this topic can be found in the section on Serialization.

Validation isn't just an option; it's an integral component of robust software design. It's always prudent to err on the side of caution: better to validate excessively than regret insufficient checks later. Deepkit understands this importance, offering a plethora of validation tools. What's more, its high-performance design ensures minimal impact on execution times. As a guiding principle, employ comprehensive validation to safeguard your application, even if it feels redundant at times.

Many of Deepkit's components, including the HTTP router, the RPC abstraction, and even the database abstraction, come with embedded validation systems. These mechanisms are automatically triggered, often eliminating the need for manual intervention.


For a comprehensive understanding of when and how automatic validation occurs, refer to specific chapters ([CLI](https://deepkit.io/en/documentation/app.md), [HTTP](https://deepkit.io/en/documentation/http.md), [RPC](https://deepkit.io/en/documentation/rpc.md), [ORM](https://deepkit.io/en/documentation/orm.md)). 
Familiarize yourself with the necessary constraints and data types. Properly defined parameters can unlock Deepkit's automated validation potential, reducing manual labor and ensuring cleaner, more secure code.

## Usage

The basic function of the validator is to check a value for its type. For example, whether a value is a string. This is not about what the string contains, but only about its type. There are many types in Typescript: string, number, boolean, bigint, objects, classes, interface, generics, mapped types, and many more. Due to Typescript’s powerful type system, a large variety of different types are available.

In JavaScript itself, primitive types can be parsed with the `typeof` operator. For more complex types like interfaces, mapped types, or generic set/map this is not so easy anymore and a validator library like `@deepkit/type` becomes necessary. Deepkit is the only solution that allows to validate all TypesScript types directly without any workarounds.



In Deepkit, type validation can be done using either the `validate`, `is`, or `assert` function.
The function `is` is a so-called type guard and `assert` is a type assertion. Both will be explained in the next section.
The function `validate` returns an array of found errors and on success an empty array. Each entry in this array describes the exact error code and the error message as well as the path when more complex types like objects or arrays are validated.

All three functions are used in roughly the same way. The type is specified or referenced as the first type argument and the data is passed as the first function argument.

```typescript
import { validate, is, assert } from '@deepkit/type';

const errors = validate<string>('abc'); //[]
const errors = validate<string>(123); //[{code: 'type', message: 'Not a string'}]

if (is<string>(value)) {
    // value is guaranteed to be a string
}

function doSomething(value: any) {
    assert<string>(value); //throws on invalid data

    // value is guaranteed to be a string
}
```

If you work with more complex types like classes or interfaces, the array can also contain several entries.

```typescript
import { validate } from '@deepkit/type';

interface User {
    id: number;
    username: string;
}

validate<User>({id: 1, username: 'Joe'}); //[]

validate<User>(undefined); //[{code: 'type', message: 'Not a object'}]

validate<User>({});
//[
//  {path: 'id', code: 'type', message: 'Not a number'}],
//  {path: 'username', code: 'type', message: 'Not a string'}],
//]
```

The validator also supports deep recursive types. Paths are then separated with a dot.

```typescript
import { validate } from '@deepkit/type';

interface User {
    id: number;
    username: string;
    supervisor?: User;
}

validate<User>({id: 1, username: 'Joe'}); //[]

validate<User>({id: 1, username: 'Joe', supervisor: {}});
//[
//  {path: 'supervisor.id', code: 'type', message: 'Not a number'}],
//  {path: 'supervisor.username', code: 'type', message: 'Not a string'}],
//]
```

Take advantage of the benefits that TypeScript offers you. For example, more complex types like a `User` can be reused in multiple places without having to declare it again and again. For example, if a `User` is to be validated without its `id`, TypeScript utitilies can be used to quickly and efficiently create derived subtypes. Very much in the spirit of DRY (Don't Repeat Yourself).

```typescript
type UserWithoutId = Omit<User, 'id'>;

validate<UserWithoutId>({username: 'Joe'}); //valid!
```

Deepkit is the only major framework that has the ability to access TypeScripts types in this way at runtime. If you want to use types in frontend and backend, types can be swapped out to a separate file and thus imported anywhere. Use this option to your advantage to keep the code efficient and clean.

## Type Casts are Unsafe

A type cast (contrary to type guard) in TypeScript is not a construct at runtime, but is only handled in the type system itself. It is not a safe way to assign a type to unknown data.

```typescript
const data: any = ...;

const username = data.username as string;

if (username.startsWith('@')) { //might crash
}
```

The `as string` code is not safe. The variable `data` could have literally any value, for example `{username: 123}`, or even `{}`, and would have the consequence that `username` is not a string, but something completely different and therefore the code `username.startsWith('@')` will lead to an error, so that in a base case the program crashes and in the worst case a security vulnerability is created.
To guarantee at runtime that `data` here has a property `username` with the type string, type-guards must be used.

Type guards are functions that give TypeScript a hint about what type the passed data is guaranteed to have at runtime. Armed with this knowledge, TypeScript then "narrows" the type as the code progresses. For example, `any` can be made into a string, or any other type in a safe way. So if there is data of which the type is not known (`any` or `unknown`), a type guard helps to narrow it down more precisely based on the data itself. However, the type guard is only as safe as its implementation. If you make a mistake, this can have severe consequences, because fundamental assumptions suddenly turn out to be untrue.

<a name="type-guard"></a>

## Type-Guard

A type guard on the above used type `User` could look in the simplest form as follows. Note that the above explained special features with NaN are not part here and thus this type guard is not quite correct.

```typescript
function isUser(data: any): data is User {
    return 'object' === typeof data
           && 'number' === typeof data.id
           && 'string' === typeof data.username;
}

isUser({}); //false

isUser({id: 1, username: 'Joe'}); //true
```

A type guard always returns a Boolean and is usually used directly in an If operation.

```typescript
const data: any = await fetch('/user/1');

if (isUser(data)) {
    data.id; //can be safely accessed and is a number
}
```

Writing a separate function for each type guard, especially for more complex types, and then adapting it every time a type changes is extremely tedious, error-prone, and not efficient. Therefore, Deepkit provides the function `is`, which automatically provides a Type-Guard for any TypeScript type. This then also automatically takes into account special features such as the above-mentioned problem with NaN. The function `is` does the same as `validate`, but instead of an array of errors it simply returns a boolean.

```typescript
import { is } from '@deepkit/type';

is<string>('abc'); //true
is<string>(123); //false


const data: any = await fetch('/user/1');

if (is<User>(data)) {
    //data is guaranteed to be of type User now
}
```

A pattern that can be found more often is to return an error directly in case of incorrect validation, so that subsequent code is not executed. This can be used in various places without changing the complete flow of the code.

```typescript
function addUser(data: any): void {
    if (!is<User>(data)) throw new TypeError('No user given');

    //data is guaranteed to be of type User now
}
```

Alternatively, a TypeScript type assertion can be used. The `assert` function automatically throws an error if the given data does not validate correctly to a type. The special signature of the function, which distinguishes TypeScript type assertions, helps TypeScript to automatically narrow the passed variable.

```typescript
import { assert } from '@deepkit/type';

function addUser(data: any): void {
    assert<User>(data); //throws on invalidate data

    //data is guaranteed to be of type User now
}
```

Here, too, take advantage of the benefits that TypeScript offers you. Types can be reused or customized using various TypeScript functions.

<a name="error-reporting"></a>

## Error Reporting

The functions `is`, `assert` and `validates` return a boolean as result. To get exact information about failed validation rules, the `validate` function can be used. It returns an empty array if everything was validated successfully. In case of errors the array will contain one or more entries with the following structure:

```typescript
interface ValidationErrorItem {
    /**
     * The path to the property. Might be a deep path separated by dot.
     */
    path: string;
    /**
     * A lower cased error code that can be used to identify this error and translate.
     */
    code: string,
    /**
     * Free text of the error.
     */
    message: string,
}
```

The function receives as first type argument any TypeScript type and as first argument the data to validate.

```typescript
import { validate } from '@deepkit/type';

validate<string>('Hello'); //[]
validate<string>(123); //[{code: 'type', message: 'Not a string', path: ''}]

validate<number>(123); //[]
validate<number>('Hello'); //[{code: 'type', message: 'Not a number', path: ''}]
```

Complex types such as interfaces, classes, or generics can also be used.

```typescript
import { validate } from '@deepkit/type';

interface User {
    id: number;
    username: string;
}

validate<User>(undefined); //[{code: 'type', message: 'Not an object', path: ''}]
validate<User>({}); //[{code: 'type', message: 'Not a number', path: 'id'}]
validate<User>({id: 1}); //[{code: 'type', message: 'Not a string', path: 'username'}]
validate<User>({id: 1, username: 'Peter'}); //[]
```

<a name="constraints"></a>

## Constraints

In addition to checking the types, other arbitrary constraints can be added to a type. The validation of these additional content constraints is done automatically after the types themselves have been validated. This is done in all validation functions like `validate`, `is`, and `assert`.
A restriction can be, for example, that a string must have a certain minimum or maximum length. These restrictions are added to the actual types via [Type Annotations](https://deepkit.io/en/documentation/runtime-types/types.md). There is a whole variety of annotations that can be used. Own annotations can be defined and used at will in case of extended needs.

```typescript
import { MinLength } from '@deepkit/type';

type Username = string & MinLength<3>;
```

With `&` any number of type annotations can be added to the actual type. The result, here `username`, can then be used in all validation functions but also in other types.

```typescript
import { is } from '@deepkit/type';

is<Username>('ab'); //false, because minimum length is 3
is<Username>('Joe'); //true

interface User {
  id: number;
  username: Username;
}

is<User>({id: 1, username: 'ab'}); //false, because minimum length is 3
is<User>({id: 1, username: 'Joe'}); //true
```

The function `validate` gives useful error messages coming from the constraints.

```typescript
import { validate } from '@deepkit/type';

const errors = validate<Username>('xb');
//[{ code: 'minLength', message: `Min length is 3` }]
```

This information can be represented for example wonderfully also at a form automatically and be translated by means of the `code`. Through the existing path for objects and arrays, fields in a form can filter out and display the appropriate error.

```typescript
validate<User>({id: 1, username: 'ab'});
//{ path: 'username', code: 'minLength', message: `Min length is 3` }
```

An often useful use case is also to define an email with a RegExp constraint. Once the type is defined, it can be used anywhere.

```typescript
export const emailRegexp = /^\S+@\S+$/;
type Email = string & Pattern<typeof emailRegexp>

is<Email>('abc'); //false
is<Email>('joe@example.com'); //true
```

Any number of constraints can be added.

```typescript
type ID = number & Positive & Maximum<1000>;

is<ID>(-1); //false
is<ID>(123); //true
is<ID>(1001); //true
```

### Constraint Types

#### Validate<typeof myValidator>

Validation using a custom validator function. See next section Custom Validator for more information.

```typescript
import { ValidatorError, Validate } from '@deepkit/type';

function startsWith(v: string) {
    return (value: any) => {
        const valid = 'string' === typeof value && value.startsWith(v);
        return valid ? undefined : new ValidatorError('startsWith', `Does not start with ${v}`);
    };
}

type T = string & Validate<typeof startsWith, 'abc'>;
```

#### Pattern<typeof myRegexp>

Defines a regular expression as validation pattern. Usually used for E-Mail validation or more complex content validation.

```typescript
import { Pattern } from '@deepkit/type';

const myRegExp = /[a-zA-Z]+/;
type T = string & Pattern<typeof myRegExp>
```

#### Alpha

Validation for alpha characters (a-Z).

```typescript
import { Alpha } from '@deepkit/type';

type T = string & Alpha;
```


#### Alphanumeric

Validation for alpha and numeric characters.

```typescript
import { Alphanumeric } from '@deepkit/type';

type T = string & Alphanumeric;
```


#### Ascii

Validation for ASCII characters.

```typescript
import { Ascii } from '@deepkit/type';

type T = string & Ascii;
```


#### Decimal<number, number>

Validation for string represents a decimal number, such as 0.1, .3, 1.1, 1.00003, 4.0, etc.

```typescript
import { Decimal } from '@deepkit/type';

type T = string & Decimal<1, 2>;
```


#### MultipleOf<number>

Validation of numbers that are a multiple of given number.

```typescript
import { MultipleOf } from '@deepkit/type';

type T = number & MultipleOf<3>;
```


#### MinLength<number>, MaxLength<number>, MinMax<number, number>

Validation for min/max length for arrays or strings.

```typescript
import { MinLength, MaxLength, MinMax } from '@deepkit/type';

type T = any[] & MinLength<1>;

type T = string & MinLength<3> & MaxLength<16>;

type T = string & MinMax<3, 16>;
```

#### Includes<'any'> Excludes<'any'>

Validation for an array item or sub string being included/excluded

```typescript
import { Includes, Excludes } from '@deepkit/type';

type T = any[] & Includes<'abc'>;
type T = string & Excludes<' '>;
```

#### Minimum<number>, Maximum<number>

Validation for a value being minimum or maximum given number. Same as `>=` and `<=`.

```typescript
import { Minimum, Maximum, MinMax } from '@deepkit/type';

type T = number & Minimum<10>;
type T = number & Minimum<10> & Maximum<1000>;

type T = number & MinMax<10, 1000>;
```

#### ExclusiveMinimum<number>, ExclusiveMaximum<number>

Same as minimum/maximum but excludes the value itself. Same as `>` and `<`.

```typescript
import { ExclusiveMinimum, ExclusiveMaximum } from '@deepkit/type';

type T = number & ExclusiveMinimum<10>;
type T = number & ExclusiveMinimum<10> & ExclusiveMaximum<1000>;
```


#### Positive, Negative, PositiveNoZero, NegativeNoZero

Validation for a value being positive or negative.

```typescript
import { Positive, Negative } from '@deepkit/type';

type T = number & Positive;
type T = number & Negative;
```


#### BeforeNow, AfterNow

Validation for a date value compared to now (new Date)..

```typescript
import { BeforeNow, AfterNow } from '@deepkit/type';

type T = Date & BeforeNow;
type T = Date & AfterNow;
```

#### Email

Simple regexp validation of emails via `/^\S+@\S+$/`. Is automatically a `string`, so no need to do `string & Email`.

```typescript
import { Email } from '@deepkit/type';

type T = Email;
```

#### integer

Ensures that the number is an integer in the correct range. Is automatically a `number`, so no need to do `number & integer`.

```typescript
import { integer, uint8, uint16, uint32, 
    int8, int16, int32 } from '@deepkit/type';

type T = integer;
type T = uint8;
type T = uint16;
type T = uint32;
type T = int8;
type T = int16;
type T = int32;
```

See Special types: integer/floats for more information

### Custom validator

If the built-in validators are not sufficient, custom validation functions can be created and used via the `Validate` decorator.

```typescript
import { ValidatorError, Validate, Type, validates, validate }
  from '@deepkit/type';

function titleValidation(value: string, type: Type) {
    value = value.trim();
    if (value.length < 5) {
        return new ValidatorError('tooShort', 'Value is too short');
    }
}

interface Article {
    id: number;
    title: string & Validate<typeof titleValidation>;
}

console.log(validates<Article>({id: 1})); //false
console.log(validates<Article>({id: 1, title: 'Peter'})); //true
console.log(validates<Article>({id: 1, title: ' Pe     '})); //false
console.log(validate<Article>({id: 1, title: ' Pe     '})); //[ValidationErrorItem]
```

Note that your custom validation function is executed after all built-in type validators have been called. If a validator fails, all subsequent validators for the current type are skipped. Only one failure is possible per type.

#### Generic Validator

In the Validator function the type object is available which can be used to get more information about the type using the validator. There is also a possibility to define an arbitrary validator option that must be passed to the validate type and makes the validator configurable. With this information and its parent references, powerful generic validators can be created.

```typescript
import { ValidatorError, Validate, Type, is, validate }
  from '@deepkit/type';

function startsWith(value: any, type: Type, chars: string) {
    const valid = 'string' === typeof value && value.startsWith(chars);
    if (!valid) {
        return new ValidatorError('startsWith', 'Does not start with ' + chars)
    }
}

type MyType = string & Validate<typeof startsWith, 'a'>;

is<MyType>('aah'); //true
is<MyType>('nope'); //false

const errors = validate<MyType>('nope');
//[{ path: '', code: 'startsWith', message: `Does not start with a` }]);
```

---

Source: https://deepkit.io/en/documentation/runtime-types/extend

# Extend

## Custom Serialization

You can extend the serialization of a type by defining either write your own `Serializer` or extend the default `serializer`.

This example shows how to serialize and deserialize a class `Point` to a tuple `[number, number]`.

```typescript
import { serializer, SerializationError } from '@deepkit/type';

class Point {
  constructor(public x: number, public y: number) {
  }
}

// deserialize means from JSON to (class) instance.
serializer.deserializeRegistry.registerClass(Point, (type, state) => {
  state.convert((v: any) => {
    // if it's already a Point instance, we are done
    if (v instanceof Point) return v;

    // at this point `v` could be anything (except undefined), so we need to check
    if (!Array.isArray(v)) throw new SerializationError('Expected array');
    if (v.length !== 2) throw new SerializationError('Expected array with two elements');
    if (typeof v[0] !== 'number' || typeof v[1] !== 'number') throw new SerializationError('Expected array with two numbers');
    return new Point(v[0], v[1]);
  });
});

serializer.serializeRegistry.registerClass(Point, (type, state) => {
  state.convert((v: Point) => {
    // at this point `v` is always a Point instance
    return [v.x, v.y];
  });
});

// cast and deserialize use `serializer` by default
const point = cast<Point>([1, 2], undefined, serializer);
expect(point).toBeInstanceOf(Point);
expect(point.x).toBe(1);
expect(point.y).toBe(2);

{
  expect(() => deserialize<Point>(['vbb'])).toThrowError(SerializationError);
  expect(() => deserialize<Point>(['vbb'])).toThrow('Expected array with two elements')
}

// serialize uses `serializer` by default
const json = serialize<Point>(point);
expect(json).toEqual([1, 2]);
```

Please note that this is only working for the regular `@deepkit/type` functions like `cast`, `deserialize`, and `serialize`.

This won't be transferred to the database layer, since the database layer uses the types as defined in the Entity class for migration and serialization (e.g. BSON serialization).

---

Source: https://deepkit.io/en/documentation/runtime-types/custom-serializer

# Custom Serializer

By default, `@deepkit/type` comes with a JSON serializer and type validation for TypeScript types. You can extend this and add or remove the serialization functionality or change the way validation is done, as validation is also linked to the serializer.

## New Serializer

A serializer is simply an instance of the `Serializer` class with registered serializer templates. Serializer templates are small functions that create JavaScript code for the JIT serializer process. For each type (String, Number, Boolean, etc.) there is a separate Serializer template that is responsible for returning code for data conversion or validation. This code must be compatible with the JavaScript engine that the user is using.

Only during the execution of the compiler template function do you (or should you) have full access to the full type. The idea is that you should embed all the information needed to convert a type directly into the JavaScript code, resulting in highly optimized code (also called JIT-optimized code).

The following example creates an empty serializer.

```typescript
import { EmptySerializer } from '@deepkit/type';

class User {
    name: string = '';
    created: Date = new Date;
}

const mySerializer = new EmptySerializer('mySerializer');

const user = deserialize<User>({ name: 'Peter', created: 0 }, undefined, mySerializer);
console.log(user);
```

```sh
$ ts-node app.ts
User { name: 'Peter', created: 0 }
```

As you can see, nothing has been converted (`created` is still a number, but we have defined it as `Date`). To change this, we add a serializer template for deserialization of type Date.

```typescript
mySerializer.deserializeRegistry.registerClass(Date, (type, state) => {
    state.addSetter(`new Date(${state.accessor})`);
});

const user = deserialize<User>({ name: 'Peter', created: 0 }, undefined, mySerializer);
console.log(user);
```

```sh
$ ts-node app.ts
User { name: 'Peter', created: 2021-06-10T19:34:27.301Z }
```

Now our serializer converts the value into a Date object.

To do the same for serialization, we register another serialization template.

```typescript
mySerializer.serializeRegistry.registerClass(Date, (type, state) => {
    state.addSetter(`${state.accessor}.toJSON()`);
});

const user1 = new User();
user1.name = 'Peter';
user1.created = new Date('2021-06-10T19:34:27.301Z');
console.log(serialize(user1, undefined, mySerializer));
```

```sh
{ name: 'Peter', created: '2021-06-10T19:34:27.301Z' }
```

Our new serializer now correctly converts the date from the Date object to a string in the serialization process.

## Examples

To see many more examples, you can take a look at the code of the [JSON-Serializers](https://github.com/deepkit/deepkit-framework/blob/master/packages/type/src/serializer.ts#L1688) included in Deepkit Type.

## Extending Existing Serializer

If you want to extend an existing serializer, you can do so using class inheritance. This works because serializers should be written to register their templates in the constructor.

```typescript
class MySerializer extends Serializer {
    constructor(name: string = 'mySerializer') {
        super(name);
        this.registerTemplates();
    }

    protected registerTemplates() {
        this.deserializeRegistry.register(ReflectionKind.string, (type, state) => {
            state.addSetter(`String(${state.accessor})`);
        });

        this.deserializeRegistry.registerClass(Date, (type, state) => {
            state.addSetter(`new Date(${state.accessor})`);
        });

        this.serializeRegistry.registerClass(Date, (type, state) => {
            state.addSetter(`${state.accessor}.toJSON()`);
        });
    }
}
const mySerializer = new MySerializer();
```

---

Source: https://deepkit.io/en/documentation/runtime-types/external-types

# External Types

## External Classes

Since TypeScript does not include type information per default, imported types/classes from other packages (that did not use @deepkit/type-compiler) will not have type information available.

To annotate types for an external class, use `annotateClass` and make sure this function is executed in the bootstrap phase of your application before the imported class is used somewhere else.

```typescript
import { MyExternalClass } from 'external-package';
import { annotateClass } from '@deepkit/type';

interface AnnotatedClass {
    id: number;
    title: string;
}

annotateClass<AnnotatedClass>(MyExternalClass);

//all uses of MyExternalClass return now the type of AnnotatedClass
serialize<MyExternalClass>({...});

//MyExternalClass can now also be used in other types
interface User {
    id: number;
    clazz: MyExternalClass;
}
```

`MyExternalClass` can now be used in serialization functions and in the reflection API.

To following shows how to annotate generic classes:

```typescript
import { MyExternalClass } from 'external-package';
import { annotateClass } from '@deepkit/type';

class AnnotatedClass<T> {
    id!: T;
}

annotateClass(ExternalClass, AnnotatedClass);
```

## Import Type

The `import type` syntax is designed by TypeScript to avoid importing actual JavaScript code and use it only for type-checking. This is useful for example when you want to use a type from a package that is not available at runtime, but only at compile-time or if you don't want to actually load that package at runtime.

Deepkit supports the reasoning of `import type` and will not generate any runtime code. This means if you use `import type`, no type information will be available at runtime.

---

Source: https://deepkit.io/en/documentation/runtime-types/bytecode

# Bytecode

To learn in detail how Deepkit encodes and reads the type information in JavaScript, this chapter is intended. It explains how the types are actually converted into bytecode, emitted in JavaScript, and then interpreted at runtime.

## Typen-Compiler

The type compiler (in @deepkit/type-compiler) is responsible for reading the defined types in the TypeScript files and compiling them into a bytecode. This bytecode has everything needed to execute the types in runtime.
At the time of this writing, the type compiler is a so-called TypeScript transformer. This transformer is a plugin for the TypeScript compiler itself and converts a TypeScript AST (Abstract Syntax Tree) into another TypeScript AST. Deepkit's type compiler reads the AST in this process, produces the corresponding bytecode, and inserts it into the AST.

TypeScript itself does not allow you to configure this plugin aka transformer via a tsconfig.json. It is either necessary to use the TypeScript compiler API directly, or a build system like Webpack with `ts-loader`. To save this inconvenient way for Deepkit users, the Deepkit type compiler automatically installs itself in `node_modules/typescript` whenever `@deepkit/type-compiler` is installed. This makes it possible for all build tools that access the locally installed TypeScript (the one in `node_modules/typescript`) to automatically have the type compiler enabled. This makes tsc, Angular, webpack, ts-node, and some other tools work automatically with Deepkit's type compiler.

If automatic running of NPM install scripts is not enabled and thus the locally installed typescript is not modified, this process must be run manually if you want to. Alternatively, the types compiler can be used manually in a build tool such as webpack. See the Installation section above.

## Bytecode Encoding

The bytecode is a sequence of commands for a virtual machine and is encoded in the JavaScript itself as an array of references and string (the actual bytecode).

```typescript
//TypeScript
type TypeA = string;

//generated JavaScript
const typeA = ['&'];
```

The existing commands themselves are each one byte in size and can be found in `@deepkit/type-spec` as `ReflectionOp` enums. At the time of this writing, the command set is over 81 commands in size.

```typescript
enum ReflectionOp {
    never,
    any,
    unknown,
    void,
    object,

    string,
    number,

    //...many more
}
```

A sequence of commands is encoded as a string to save memory. So a type `string[]` is conceptualized as a bytecode program `[string, array]` which has the bytes `[5, 37]` and encoded with the following algorithm:

```typescript
function encodeOps(ops: ReflectionOp[]): string {
    return ops.map(v => String.fromCharCode(v + 33)).join('');
}
```

Accordingly, a 5 becomes an `&` character and a 37 becomes an `F` character. Together they become `&F` and are emitted in Javascript as `['&F']`.

```typescript
//TypeScript
export type TypeA = string[];

//generated JavaScript
export const __ΩtypeA = ['&F'];
```

To prevent naming conflicts, each type is given a "_Ω" prefix. For each explicitly defined type that is exported or used by an exported type, a bytecode is emitted the JavaScript. Classes and functions also receive a bytecode directly as a property.

```typescript
//TypeScript
function log(message: string): void {}

//generated JavaScript
function log(message) {}
log.__type = ['message', 'log', 'P&2!$/"'];
```

## Virtual Machine

A virtual machine (in `@deepkit/type` the class Processor) at runtime is responsible for decoding and executing the encoded bytecode. It always returns a type object as described in the [Reflection API](https://deepkit.io/en/documentation/runtime-types/reflection.md).

More information can be found in [TypeScript Bytecode Interpreter / Runtime Types #47658](https://github.com/microsoft/TypeScript/issues/47658)

---

Source: https://deepkit.io/en/documentation/dependency-injection

# Dependency Injection

Dependency Injection (DI) is a design pattern in which classes and functions _receive_ their dependencies. It follows the principle of Inversion of Control (IoC) and helps to better separate complex code in order to significantly improve testability, modularity and clarity. Although there are other design patterns, such as the service locator pattern, for applying the principle of IoC, DI has established itself as the dominant pattern, especially in enterprise software.

To illustrate the principle of IoC, here is an example:

```typescript
import { HttpClient } from 'http-library';

class UserRepository {
    async getUsers(): Promise<Users> {
        const client = new HttpClient();
        return await client.get('/users');
    }
}
```

The UserRepository class has an HttpClient as a dependency. This dependency in itself is nothing remarkable, but it is problematic that `UserRepository` creates the HttpClient itself.
It seems to be a good idea to encapsulate the creation of the HttpClient in the UserRepository, but this is not the case. What if we want to replace the HttpClient? What if we want to test UserRepository in a unit test without allowing real HTTP requests to go out? How do we know that the class even uses an HttpClient?

## Inversion of Control

In the thought of Inversion of Control (IoC) is the following alternative variant that sets the HttpClient as an explicit dependency in the constructor (also known as constructor injection).

```typescript
class UserRepository {
    constructor(
        private http: HttpClient
    ) {}

    async getUsers(): Promise<Users> {
        return await this.http.get('/users');
    }
}
```

Now UserRepository is no longer responsible for creating the HttpClient, but the user of UserRepository. This is Inversion of Control (IoC). The control has been reversed or inverted. Specifically, this code applies dependency injection, because dependencies are received (injected) and no longer created or requested. Dependency Injection is only one variant of IoC.

## Service Locator

Besides DI, Service Locator (SL) is also a way to apply the IoC principle. This is commonly considered the counterpart to Dependency Injection, as it requests dependencies rather than receiving them. If HttpClient were requested in the above code as follows, it would be called a Service Locator pattern.

```typescript
class UserRepository {
    async getUsers(): Promise<Users> {
        const client = locator.getHttpClient();
        return await client.get('/users');
    }
}
```

The function `locator.getHttpClient` can have any name. Alternatives would be function calls like `useContext(HttpClient)`, `getHttpClient()`, `await import("client"),` or a container queries like `container.get(HttpClient)` or `container.http`. An import of a global is a slightly different variant of a service locator, using the module system itself as the locator:

```typescript
import { httpClient } from 'clients'

class UserRepository {
    async getUsers(): Promise<Users> {
        return await httpClient.get('/users');
    }
}
```

All these variants have in common that they explicitly request the HttpClient dependency and the code is aware that there is a service container. It tightly couples your code to the framework and is something you want to avoid to keep the code clean. 

The service request can happen not only to properties as a default value, but also somewhere in the middle of the code. Since in the middle of the code means that it is not part of a type interface, the use of the HttpClient is hidden. Depending on the variant of how the HttpClient is requested, it can sometimes be very difficult or completely impossible to replace it with another implementation. Especially in the area of unit tests and for the sake of clarity, difficulties can arise here, so that the service locator is now classified as an anti-pattern in certain situations.

## Dependency Injection

With Dependency Injection, nothing is requested, but it is explicitly provided by the user or received by the code. The consumer does not have access to any service container, does not know how `HttpClient` is created or retrieved. In its core it allows your code to be decoupled from the IoC framework making it cleaner. 

It just declares that it needs an `HttpClient` as a type. One key differentiator and advantage of Dependency Injection over Service Locator is that the code using Dependency Injection works perfectly fine without any kind of service container and service identification system (you don't have to give your service a name). It is just a type declaration that works out of the IoC framework context as well.

As can be seen in the example earlier, the dependency injection pattern has already been applied there. Specifically, constructor injection can be seen there, since the dependency is declared in the constructor. So UserRepository must now be instantiated as follows.

```typescript
const users = new UserRepository(new HttpClient());
```

The code that wants to use UserRepository must also provide (inject) all its dependencies. Whether HttpClient should be created each time or the same one should be used each time is now decided by the user of the class and no longer by the class itself. It is no longer requested (from the class's point of view) as in the case of the service locator, or created entirely by itself in the initial example. This inversion of the flow has various advantages:

* The code is easier to understand because all dependencies are explicitly visible.
* The code is easier to test because all dependencies are unique and can be easily modified if needed.
* The code is more modular, as dependencies can be easily exchanged.
* It promotes the Separation of Concern principle, as UserRepository is no longer responsible for creating very complex dependencies itself.

But an obvious disadvantage can also be seen directly: Do I really need to create or manage all dependencies like the HttpClient myself? Yes and No. Yes, there are many cases where it is perfectly legitimate to manage the dependencies yourself. The hallmark of a good API is that dependencies don't get out of hand, and that even then they are pleasant to use. For many applications or complex libraries, this may well be the case. To provide a very complex low-level API with many dependencies in a simplified way to the user, the facade pattern is wonderfully suitable.

## Dependency Injection Container

For more complex applications, however, it is not necessary to manage all dependencies yourself, because that is exactly what a so-called dependency injection container is for. This not only creates all objects automatically, but also "injects" the dependencies automatically, so that a manual "new" call is no longer necessary. There are various types of injection, such as constructor injection, method injection, or property injection. This makes it easy to manage even complicated architectures with many dependencies.

A dependency injection container (also called DI container or IoC container) brings Deepkit in `@deepkit/injector` or already ready integrated via App modules in the Deepkit Framework. The above code would look like this using a low-level API from the `@deepkit/injector` package.

```typescript
import { InjectorContext } from '@deepkit/injector';

const injector = InjectorContext.forProviders(
    [UserRepository, HttpClient]
);

const userRepo = injector.get(UserRepository);

const users = await userRepo.getUsers();
```

The `injector` object in this case is the dependency injection container. Instead of using "new UserRepository", the container returns an instance of UserRepository using `get(UserRepository)`. To statically initialize the container, a list of providers is passed to the `InjectorContext.forProviders` function (in this case, simply the classes).
Since DI is all about providing dependencies, the container is provided with the dependencies, hence the technical term "provider". 

There are several types of providers: ClassProvider, ValueProvider, ExistingProvider, FactoryProvider. All together, they allow very flexible architectures to be mapped with a DI container.

All dependencies between providers are automatically resolved and as soon as an `injector.get()` call occurs, the objects and dependencies are created, cached, and correctly passed either as a constructor argument (which is known as constructor injection), set as a property (which is known as property injection), or passed to a method call (which is known as method injection).

Now to exchange the HttpClient with another one, another provider (here the ValueProvider) can be defined for HttpClient:

```typescript
const injector = InjectorContext.forProviders([
    UserRepository,
    {provide: HttpClient, useValue: new AnotherHttpClient()},
]);
```

As soon as UserRepository is requested via `injector.get(UserRepository)`, it receives the AnotherHttpClient object. Alternatively, a ClassProvider can be used here very well, so that all dependencies of AnotherHttpClient are also managed by the DI container.

```typescript
const injector = InjectorContext.forProviders([
    UserRepository,
    {provide: HttpClient, useClass: AnotherHttpClient},
]);
```

All types of providers are listed and explained in the [Dependency Injection Providers](https://deepkit.io/en/documentation/dependency-injection/providers.md) section.

It should be mentioned here that Deepkit's DI container only works with Deepkit's runtime types. This means that any code that contains classes, types, interfaces, and functions must be compiled by the Deepkit Type Compiler in order to have the type information available at runtime. See the chapter [Runtime Types](https://deepkit.io/en/documentation/runtime-types.md).

## Dependency Inversion

The example of UserRepository earlier shows that UserRepository depends on a lower level HTTP library. In addition, a concrete implementation (class) is declared as a dependency instead of an abstraction (interface). At first glance, this may seem to be in line with the object-oriented paradigms, but it can lead to problems, especially in complex and large architectures.

An alternative variant would be to convert the HttpClient dependency into an abstraction (interface) and thus not import code from an HTTP library into UserRepository.

```typescript
interface HttpClientInterface {
   get(path: string): Promise<any>;
}

class UserRepository {
    concstructor(
        private http: HttpClientInterface
    ) {}

    async getUsers(): Promise<Users> {
        return await this.http.get('/users');
    }
}
```

This is called the dependency inversion principle. UserRepository no longer has a dependency directly on an HTTP library and is instead based on an abstraction (interface). It thus solves two fundamental goals in this principle:

* High-level modules should not import anything from low-level modules.
* Implementations should be based on abstractions (interfaces).

Merging the two implementations (UserRepository with an HTTP library) can now be done via the DI container.

```typescript
import { InjectorContext } from '@deepkit/injector';
import { HttpClient } from './http-client';
import { UserRepository } from './user-repository';

const injector = InjectorContext.forProviders([
    UserRepository,
    HttpClient,
]);
```

Since Deepkit's DI container is capable of resolving abstract dependencies (interfaces) such as this one of HttpClientInterface, UserRepository automatically gets the implementation of HttpClient since HttpClient implemented the interface HttpClientInterface. 

This is done either by HttpClient specifically implementing HttpClientInterface (`class HttpClient implements HttpClientInterface`), or by HttpClient's API simply being compatible with HttpClientInterface.


As soon as HttpClient modifies its API (for example, removes the `get` method) and is thus no longer compatible with HttpClientInterface, the DI container throws an error ("the HttpClientInterface dependency was not provided"). Here the user, who wants to bring both implementations together, is in the obligation to find a solution. As an example, an adapter class could be registered here that implements HttpClientInterface and correctly forwards the method calls to HttpClient.

As an alternative, the HttpClientInterface can be provided directly with a concrete implementation.

```typescript
import { InjectorContext, provide } from '@deepkit/injector';
import { HttpClient } from './http-client';
import { UserRepository, HttpClientInterface } from './user-repository';

const injector = InjectorContext.forProviders([
    UserRepository,
    provide<HttpClientInterface>({useClass: HttpClient}),
]);
```

It should be noted here that although in theory the dependency inversion principle has its advantages, in practice it also has significant disadvantages. It not only leads to more code (since more interfaces have to be written), but also to more complexity (since each implementation now has an interface for each dependency). This price to pay is only worth it when the application reaches a certain size and this flexibility is needed. Like any design pattern and principle, this one has its cost-use factor, which should be thought through before it is applied.

Design patterns should not be used blindly and across the board for even the simplest code. However, if the prerequisites such as a complex architecture, large applications, or a scaling team are given, dependency inversion and other design patterns only unfold their true strength.

---

Source: https://deepkit.io/en/documentation/dependency-injection/getting-started

# Getting Started

Since Dependency Injection in Deepkit is based on Runtime Types, it is necessary to have Runtime Types already installed correctly. See [Runtime Type](https://deepkit.io/en/documentation/runtime-types/getting-started.md).

If this is done successfully, `@deepkit/injector` can be installed or the Deepkit framework which already uses the library under the hood.

```sh
	npm install @deepkit/injector
```

Once the library is installed, the API of it can be used directly.


## Usage

To use Dependency Injection now, there are three ways.

* Injector API (Low Level)
* Module API
* App API (Deepkit Framework)

If `@deepkit/injector` is to be used without the Deepkit Framework, the first two variants are recommended.

### Injector API

The Injector API has already been introduced in the [introduction to Dependency Injection](https://deepkit.io/en/documentation/dependency-injection). It is characterized by a very simple usage by means of a single class `InjectorContext` that creates a single DI container and is particularly suitable for simpler applications without modules.

```typescript
import { InjectorContext } from '@deepkit/injector';

const injector = InjectorContext.forProviders([
    UserRepository,
    HttpClient,
]);

const repository = injector.get(UserRepository);
```

The `injector` object in this case is the dependency injection container. The function `InjectorContext.forProviders` takes an array of providers. See the section [Dependency Injection Providers](https://deepkit.io/en/documentation/dependency-injection/providers.md) to learn which values can be passed.

### Module API

A more complex API is the `InjectorModule` class, which allows to store the providers in different modules to create multiple encapsulated DI containers per module. Also this allows using configuration classes per module, which makes it easier to provide configuration values automatically validated to the providers. Modules can import themselves among themselves, providers export, in order to build up a hierarchy and nicely separated architecture.

This API should be used if the application is more complex and the Deepkit Framework is not used.

```typescript
import { InjectorModule, InjectorContext } from '@deepkit/injector';

const lowLevelModule = new InjectorModule([HttpClient])
     .addExport(HttpClient);

const rootModule = new InjectorModule([UserRepository])
     .addImport(lowLevelModule);

const injector = new InjectorContext(rootModule);
```

The `injector` object in this case is the dependency injection container. Providers can be split into different modules and then imported again in different places using module imports. This creates a natural hierarchy that reflects the hierarchy of the application or architecture.
The InjectorContext should always be given the top module in the hierarchy, also called root module or app module. The InjectorContext then only has an intermediary role: calls to `injector.get()` are simply forwarded to the root module. However, it is also possible to get providers from non-root modules by passing the module as a second argument.

```typescript
const repository = injector.get(UserRepository);

const httpClient = injector.get(HttpClient, lowLevelModule);
```

All non-root modules are encapsulated by default, so that all providers in this module are only available to itself. If a provider is to be available to other modules, this provider must be exported. By exporting, the provider moves to the parent module of the hierarchy and can be used that way.

To export all providers by default to the top level, the root module, the option `forRoot` can be used. This allows all providers to be used by all other modules.

```typescript
const lowLevelModule = new InjectorModule([HttpClient])
     .forRoot(); //export all Providers to the root
```

### App API

Once the Deepkit framework is used, modules are defined with the `@deepkit/app` API. This is based on the Module API, so the capabilities from there are also available. In addition, it is possible to work with powerful hooks and define configuration loaders to map even more dynamic architectures.

The [Framework Modules](https://deepkit.io/en/documentation/app/modules.md) chapter describes this in more detail.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { HttpRouterRegistry, HttpBody } from '@deepkit/http';

interface User {
    username: string;
}

class Service {
    users: User[] = [];
}

const app = new App({
    providers: [Service],
    imports: [new FrameworkModule()],
});

const router = app.get(HttpRouterRegistry);

router.post('/users', (body: HttpBody<User>, service: Service) => {
    service.users.push(body);
});

router.get('/users', (service: Service): Users => {
    return service.users;
});
```

---

Source: https://deepkit.io/en/documentation/dependency-injection/providers

# Providers

There are several ways to provide dependencies in the Dependency Injection container. The simplest variant is simply the specification of a class. This is also known as short ClassProvider.

```typescript
new App({
    providers: [UserRepository]
});
```

This represents a special provider, since only the class is specified. All other providers must be specified as object literals.

By default, all providers are marked as singletons, so only one instance exists at any given time. To create a new instance each time a provider is deployed, the `transient` option can be used. This will cause classes to be recreated each time or factories to be executed each time.

```typescript
new App({
    providers: [{ provide: UserRepository, transient: true }]
});
```

## ClassProvider

Besides the short ClassProvider there is also the regular ClassProvider, which is an object literal instead of a class.

```typescript
new App({
    providers: [{ provide: UserRepository, useClass: UserRepository }]
});
```

This is equivalent to these two:

```typescript
new App({
    providers: [{ provide: UserRepository }]
});

new App({
    providers: [UserRepository]
});
```

It can be used to exchange a provider with another class.

```typescript
new App({
    providers: [{ provide: UserRepository, useClass: OtherUserRepository }]
});
```

In this example, the `OtherUserRepository` class is now also managed in the DI container and all its dependencies are resolved automatically.

## ValueProvider

Static values can be provided with this provider.

```typescript
new App({
    providers: [{ provide: OtherUserRepository, useValue: new OtherUserRepository() }]
});
```

Since not only class instances can be provided as dependencies, any value can be specified as `useValue`. A symbol or a primitive (string, number, boolean) could also be used as a provider token.

```typescript
new App({
    providers: [{ provide: 'domain', useValue: 'localhost' }]
});
```

Primitive provider tokens must be declared with the Inject type as a dependency.

```typescript
import { Inject } from '@deepkit/core';

class EmailService {
    constructor(public domain: Inject<string, 'domain'>) {}
}
```

The combination of an inject alias and primitive provider tokens can also be used to provide dependencies from packages that do not contain runtime type information.

```typescript
import { Inject } from '@deepkit/core';
import { Stripe } from 'stripe';

export type StripeService = Inject<Stripe, '_stripe'>;

new App({
    providers: [{ provide: '_stripe', useValue: new Stripe }]
});
```

And then declared on the user side as follows:

```typescript
class PaymentService {
    constructor(public stripe: StripeService) {}
}
```

## ExistingProvider

A forwarding to an already defined provider can be defined.

```typescript
new App({
    providers: [
        {provide: OtherUserRepository, useValue: new OtherUserRepository()},
        {provide: UserRepository, useExisting: OtherUserRepository}
    ]
});
```

## FactoryProvider

A function can be used to provide a value for the provider. This function can also contain parameters, which in turn are provided by the DI container. Thus, other dependencies or configuration options are accessible.

```typescript
new App({
    providers: [
        {provide: OtherUserRepository, useFactory: () => {
            return new OtherUserRepository()
        }},
    ]
});

new App({
    providers: [
        {provide: OtherUserRepository, useFactory: (domain: RootConfiguration['domain']) => {
            return new OtherUserRepository(domain);
        }},
    ]
});

new App({
    providers: [
        Database,
        {provide: OtherUserRepository, useFactory: (database: Database) => {
            return new OtherUserRepository(database);
        }},
    ]
});
```

## InterfaceProvider

In addition to classes and primitives, abstractions (interfaces) can also be provided. This is done via the function `provide` and is particularly useful if the value to be provided does not contain any type information.

```typescript
import { provide } from '@deepkit/injector';

interface Connection {
    write(data: Uint16Array): void;
}

class Server {
   constructor (public connection: Connection) {}
}

class MyConnection {
    write(data: Uint16Array): void {}
}

new App({
    providers: [
        Server,
        provide<Connection>(MyConnection)
    ]
});
```

If multiple providers have implemented the Connection interface, the last provider is used.

As argument for provide() all other providers are possible.

```typescript
const myConnection = {write: (data: any) => undefined};

new App({
    providers: [
        provide<Connection>({ useValue: myConnection })
    ]
});

new App({
    providers: [
        provide<Connection>({ useFactory: () => myConnection })
    ]
});
```

## Asynchronous Providers

The design of `@deepkit/injector` precludes the use of asynchronous providers with an asynchronous Dependency Injection container. This is because requesting providers would also need to be asynchronous, necessitating the entire application to operate at the highest level asynchronously.

To initialize something asynchronously, this initialization should be moved to the application server bootstrap,  because there the events can be asynchronous. Alternatively, an initialization can be triggered manually.

## Configure Providers

Configuration callbacks allow to manipulate the result of a provider. This is useful for example to use another dependency injection variant, the method injection.

They can only be used with the module API or the app API and are registered above the module.

```typescript
class UserRepository  {
    private db?: Database;
    setDatabase(db: Database) {
       this.db = db;
    }
}

const rootModule = new InjectorModule([UserRepository])
     .addImport(lowLevelModule);

rootModule.configureProvider<UserRepository>(v => {
  v.setDatabase(db);
});
```

The `configureProvider` receives in the callback as the first parameter `v` the UserRepository instance on which its methods can be called.

In addition to method calls, properties can also be set.

```typescript
class UserRepository  {
    db?: Database;
}

const rootModule = new InjectorModule([UserRepository])
     .addImport(lowLevelModule);

rootModule.configureProvider<UserRepository>(v => {
  v.db = new Database();
});
```

All the callbacks are placed into a queue and executed in the order they were defined.

The calls in the queue are then executed on the actual result of the provider as soon as the provider is created. That is with a ClassProvider these are applied to the class instance, as soon as the instance is created, with a FactoryProvider on the result of the Factory, and with a ValueProvider on the Provider.

To reference not only static values, but also other providers, arbitary dependencies can be injected into the callback, by just defining them as arguments. Make sure these dependencies are known in the provider scope.

```typescript
class Database {}

class UserRepository  {
    db?: Database;
}

const rootModule = new InjectorModule([UserRepository, Database])
rootModule.configureProvider<UserRepository>((v, db: Database) => {
  v.db = db;
});
```

## Nominal types

Note that the passed type to `configureProvider`, like in the last example `UserRepository`, is not resolved using structural type checking, but by nominal types. This means for example two classes/interfaces with the same structure but different identity are not compatible. The same is true for `get<T>` calls or when a dependency is resolved. 

This differentiates to the way TypeScript type checking works, which is based on structural type checking. This design decision was made to avoid accidental misconfigurations (e.g. requesting an empty class, which is structurally compatible to any class) and to make the code more robust.


In the following example the `User1` and `User2` classes are structurally compatible, but not nominally. This means requesting `User1` will not resolve `User2` and vice versa.

```typescript

class User1 {
    name: string = '';
}

class User2 {
    name: string = '';
}

new App({
    providers: [User1, User2]
});
```

Extending classes and implementing interfaces establishes a nominal relationship.

```typescript
class UserBase {
    name: string = '';
}

class User extends UserBase {
}

const app = new App({
    providers: [User2]
});

app.get(UserBase); //returns User
```

```typescript
interface UserInterface {
    name: string;
}

class User implements UserInterface {
    name: string = '';
}

const app = new App({
    providers: [User]
});

app.get<UserInterface>(); //returns User
```

---

Source: https://deepkit.io/en/documentation/dependency-injection/injection

# Injection

It's called Dependency Injection since a dependency is injected. Injection either happens by the user (manually) or by the DI container (automatically).

## Constructor Injection

In most cases, constructor injection is used. All dependencies are specified as constructor arguments and are automatically injected by the DI container.

```typescript
class MyService {
    constructor(protected database: Database) {
    }
}
```

Optional dependencies should be marked as such, otherwise an error could be triggered if no provider can be found.

```typescript
class MyService {
    constructor(protected database?: Database) {
    }
}
```

## Property Injection

An alternative to constructor injection is property injection. This is usually used when the dependency is optional or the constructor is otherwise too full. The properties are automatically assigned once the instance is created (and thus the constructor is executed).

```typescript
import { Inject } from '@deepkit/core';

class MyService {
    //required
    protected database!: Inject<Database>;

    //or optional
    protected database?: Inject<Database>;
}
```

## Parameter Injection

In various places you can define a callback function, like for example for HTTP Routes or CLI commands. In this case you can define dependencies as parameters.
They will be automatically injected by the DI container.

```typescript
import { Database } from './db';

app.get('/', (database: Database) => {
    //...
});
```

## Injector Context

In case you want to resolve dependencies dynamically, you can inject `InjectorContext` and use it to retrieve dependencies.

```typescript
import { InjectorContext } from '@deepkit/injector';

class MyService {
    constructor(protected context: InjectorContext) {
    }

    getDatabase(): Database {
        return this.context.get(Database);
    }
}
```

This is especially useful when working with [Dependency Injection Scopes](https://deepkit.io/en/documentation/dependency-injection/scopes.md).

---

Source: https://deepkit.io/en/documentation/dependency-injection/configuration

# Configuration

The dependency injection container also allows configuration options to be injected. This configuration injection can be received via constructor injection or property injection.

The Module API supports the definition of a configuration definition, which is a regular class. By providing such a class with properties, each property acts as a configuration option. Because of the way classes can be defined in TypeScript, this allows defining a type and default values per property.

```typescript
class RootConfiguration {
    domain: string = 'localhost';
    debug: boolean = false;
}

const rootModule = new InjectorModule([UserRepository])
     .setConfigDefinition(RootConfiguration)
     .addImport(lowLevelModule);
```

The configuration options `domain` and `debug` can now be used quite conveniently typesafe in providers.

```typescript
class UserRepository {
    constructor(private debug: RootConfiguration['debug']) {}

    getUsers() {
        if (this.debug) console.debug('fetching users ...');
    }
}
```

The values of the options themselves can be set via `configure()`.

```typescript
	rootModule.configure({debug: true});
```

Options that do not have a default value but are still necessary can be provided with a `!`. This forces the user of the module to provide the value, otherwise an error will occur.

```typescript
class RootConfiguration {
    domain!: string;
}
```

## Validation

Also, all serialization and validation types from the previous chapters [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md) and [Serialization](https://deepkit.io/en/documentation/runtime-types/serialization.md) can be used to specify in great detail what type and content restrictions an option must have.

```typescript
class RootConfiguration {
    domain!: string & MinLength<4>;
}
```

## Injection

Configuration options, like other dependencies, can be safely and easily injected through the DI container as shown earlier. The simplest method is to reference a single option using the index access operator:

```typescript
class WebsiteController {
    constructor(private debug: RootConfiguration['debug']) {}

    home() {
        if (this.debug) console.debug('visit home page');
    }
}
```

Configuration options can be referenced not only individually, but also as a group. The TypeScript utility type `Partial` is used for this purpose:

```typescript
class WebsiteController {
    constructor(private options: Partial<RootConfiguration, 'debug' | 'domain'>) {}

    home() {
        if (this.options.debug) console.debug('visit home page');
    }
}
```

To get all configuration options, the configuration class can also be referenced directly:

```typescript
class WebsiteController {
    constructor(private options: RootConfiguration) {}

    home() {
        if (this.options.debug) console.debug('visit home page');
    }
}
```

However, it is recommended to reference only the configuration options that are actually used. This not only simplifies unit tests, but also makes it easier to see what is actually needed from the code.

---

Source: https://deepkit.io/en/documentation/dependency-injection/scopes

# Scopes

By default, all providers of the DI container are singletons and are therefore instantiated only once. This means that in the example of UserRepository there is always only one instance of UserRepository during the entire runtime. At no time is a second instance created, unless the user does this manually with the "new" keyword.

However, there are various use cases where a provider should only be instantiated for a short time or only during a certain event. Such an event could be, for example, an HTTP request or an RPC call. This would mean that a new instance is created for each event and after this instance is no longer used it is automatically removed (by the garbage collector).

An HTTP request is a classic example of a scope. For example, providers such as a session, a user object, or other request-related providers can be registered to this scope. To create a scope, simply choose an arbitrary scope name and then specify it with the providers.

```typescript
import { InjectorContext } from '@deepkit/injector';

class UserSession {}

const injector = InjectorContext.forProviders([
    {provide: UserSession, scope: 'http'}
]);
```

Once a scope is specified, this provider cannot be obtained directly from the DI container, so the following call will fail:

```typescript
const session = injector.get(UserSession); //throws
```

Instead, a scoped DI container must be created. This would happen every time an HTTP request comes in:

```typescript
const httpScope = injector.createChildScope('http');
```

Providers that are also registered in this scope can now be requested on this scoped DI container, as well as all providers that have not defined a scope.

```typescript
const session = httpScope.get(UserSession); //works
```

Since all providers are singleton by default, each call to `get(UserSession)` will always return the same instance per scoped container. If you create multiple scoped containers, multiple UserSessions will be created.

Scoped DI containers have the ability to set values dynamically from the outside. For example, in an HTTP scope, it is easy to set the HttpRequest and HttpResponse objects.

```typescript
const injector = InjectorContext.forProviders([
    {provide: HttpResponse, scope: 'http'},
    {provide: HttpRequest, scope: 'http'},
]);

httpServer.on('request', (req, res) => {
    const httpScope = injector.createChildScope('http');
    httpScope.set(HttpRequest, req);
    httpScope.set(HttpResponse, res);
});
```

Applications using the Deepkit framework have by default an `http`, an `rpc`, and a `cli` scope. See respectively the chapter [CLI](https://deepkit.io/en/documentation/app.md), [HTTP](https://deepkit.io/en/documentation/http.md), or [RPC](https://deepkit.io/en/documentation/rpc.md).

---

Source: https://deepkit.io/en/documentation/filesystem

# Deepkit Filesystem

Deepkit Filesystem is a filesystem abstraction for local and remote filesystems. It allows you to work with files and directories in a unified way, no matter if the files are stored locally or on a remote server.

Supported filesystems out of the box:

- Local filesystem (packaged in `@deepkit/filesystem`)
- Memory (packaged in `@deepkit/filesystem`)
- FTP (packaged in `@deepkit/filesystem-ftp`)
- SFTP (packaged in `@deepkit/filesystem-sftp`)
- AWS S3 (packaged in `@deepkit/filesystem-aws-s3`)
- Google Cloud Filesystem (packaged in `@deepkit/filesystem-google`)

## Installation

```bash
npm install @deepkit/filesystem
```

Note: If you don't use NPM, make sure peer dependencies are installed correctly.

## Usage

```typescript
import { Filesystem, FilesystemLocalAdapter } from '@deepkit/filesystem';

const adapter = new FilesystemLocalAdapter('/path/to/my/files');
const filesystem = new Filesystem(adapter);

const files = await filesystem.files();
for (const file of files) {
    console.log(file.path);
}

await filesystem.write('myFile.txt', 'Hello World');
const file = await filesystem.get('myFile.txt');
console.log(file.path, file.size, file.lastModified);

const content = await filesystem.read('myFile.txt');
```


## List Files

To list files use the `files()` method. It returns an array of `File` objects.

```typescript
const files = await filesystem.files();
for (const file of files) {
    console.log(file.path);
}
```

If the array is empty, either the folder doesn't exist or no files in there.

To list all files recursively use the `allFiles()` method.

```typescript
const files = await filesystem.allFiles();
for (const file of files) {
    console.log(file.path);
}
```

## Read File

To read a file use the `read()` method. It returns the file content as `Uint8Array`.

```typescript
const content = await filesystem.read('myFile.txt');
```

To read it as a text use the `readAsText()` method. It returns a string.

```typescript
const content = await filesystem.readAsText('myFile.txt');
```

## Write File

To write a file use the `write()` method. It accepts a `Uint8Array` or a string.

```typescript
await filesystem.write('myFile.txt', 'Hello World');
```

To write from a local file use the `writeFile()` method.

Note that the first argument is the directory, not the file name. The file name is the basename of the provided file.
You can change the file name by passing a {name: 'myFile.txt'} object as second argument. If no file extension is provided,
the extension is automatically detected.

```typescript
const path = await filesystem.writeFile('/', { path: '/path/to/local/file.txt' });

// works with UploadedFile
router.post('/upload', async (body: HttpBody<{ file: UploadedFile }>, filesystem: Filesystem, session: Session) => {
    const user = session.getUser();
    const path = await filesystem.writeFile('/user-images', body.file, { name: `user-${user.id}` });
    //path = /user-images/user-123.jpg
});
```


## Delete File

To delete a file use the `delete()` method.

```typescript
await filesystem.delete('myFile.txt');
```

This deletes the file `myFile.txt` in the root folder. If the path is a directory, it throws an error.

## Delete Directory

To delete a directory use the `deleteDirectory()` method. This deletes the directory and all files and directories inside.

```typescript
await filesystem.deleteDirectory('myFolder');
```

## Create Directory

To create a directory use the `createDirectory()` method.

```typescript
await filesystem.makeDirectory('myFolder');
```

## Move File

To move a file or directory use the `move()` method. It accepts a `File` object or a path.

```typescript
await filesystem.move('myFile.txt', 'myFolder/myFile.txt');
```

It creates the directory `myFolder` if it doesn't exist.

## Copy File

To copy a file or directory use the `copy()` method. It accepts a `File` object or a path.

```typescript
await filesystem.copy('myFile.txt', 'myFolder/myFile.txt');
```

It creates the directory `myFolder` if it doesn't exist.

## File Information

To get information about a file use the `get()` method. It returns a `File` object.

```typescript
const file: FilesystemFile = await filesystem.get('myFile.txt');
console.log(file.path, file.size, file.lastModified);
```

It returns the path, the file size in bytes, and the last modified date. Modified date might be undefined if the adapter doesn't support it.

The File object also has some handy methods:

```typescript
interface FilesystemFile {
    path: string;
    type: FileType; //file or directory
    size: number;
    lastModified?: Date;
    /**
     * Visibility of the file.
     *
     * Note that some adapters might not support reading the visibility of a file.
     * In this case, the visibility is always 'private'.
     *
     * Some adapters might support reading the visibility per file, but not when listing files.
     * In this case you have to call additional `filesystem.get(file)` to load the visibility.
     */
    visibility: FileVisibility; //public or private
    constructor(path: string, type?: FileType);
    /**
     * Returns true if this file is a symbolic link.
     */
    isFile(): boolean;
    /**
     * Returns true if this file is a directory.
     */
    isDirectory(): boolean;
    /**
     * Returns the name (basename) of the file.
     */
    get name(): string;
    /**
     * Returns true if this file is in the given directory.
     */
    inDirectory(directory: string): boolean;
    /**
     * Returns the directory (dirname) of the file.
     */
    get directory(): string;
    /**
     * Returns the extension of the file, or an empty string if not existing or a directory.
     */
    get extension(): string;
}
```

## File Exists

To check if a file exists use the `exists()` method.

```typescript

if (await filesystem.exists('myFile.txt')) {
    console.log('File exists');
}
```

## File Visibility

Deepkit Filesystems supports a simple file visibility abstraction that can be used to make files public or private. 

This is useful for example for S3 or Google Cloud Filesystem. For local filesystem it sets the file permissions depending on the visibility.

To set the visibility of a file use either the `setVisibility()` method or pass the visibility as third argument to `write()`.

```typescript
await filesystem.setVisibility('myFile.txt', 'public');
await filesystem.write('myFile.txt', 'Hello World', 'public');
```

To get the visibility of a file use the `getVisibility()` method or check `FilesystemFile.visibility`.

```typescript
const visibility = await filesystem.getVisibility('myFile.txt');
const file = await filesystem.get('myFile.txt');
console.log(file.visibility);
```

Note that some adapters might not support getting the visibility from `sotrage.files()`. In this case the visibility is always `unknown`.

## File Public URL

To get the public URL of a file use the `publicUrl()` method. This only works if the file is public and the adapter supports it.

```typescript
const url = filesystem.publicUrl('myFile.txt');
```

If the adapter doesn't support public urls, the Filesystem abstraction handles it generating an url by using `option.baseUrl`.

```typescript
const filesystem = new Filesystem(new FilesystemLocalAdapter('/path/to/my/files'), {
    baseUrl: 'https://my-domain.com/assets/'
});

const url = await filesystem.publicUrl('myFile.txt');
console.log(url); //https://my-domain.com/assets/myFile.txt
```

## Filesystem Options

The `Filesystem` constructor accepts a second argument with options.

```typescript
const filesystem = new Filesystem(new FilesystemLocalAdapter('/path/to/my/files'), {
    visibility: 'private', //default visibility for files
    directoryVisibility: 'private', //default visibility for directories
    pathNormalizer: (path: string) => path, //normalizes the path. By default it replaces `[^a-zA-Z0-9\.\-\_]` with `-`.
    urlBuilder: (path: string) => path, //builds the public url for a file. By default it returns baseUrl + path
    baseUrl: '', //base url for public urls
});

---

Source: https://deepkit.io/en/documentation/filesystem/app

# App

Although Deepkit Storage works standalone, you probably want to use it in your Deepkit App using Dependency Injection.

```typescript
import { App } from '@deepkit/app';
import { Filesystem, FilesystemLocalAdapter, provideFilesystem } from '@deepkit/filesystem';

const app = new App({
    providers: [
        provideFilesystem(new FilesystemLocalAdapter({root: __dirname + '/public'})),
    ]
});

app.command('write', async (content: string, fs: Filesystem) => {
    await fs.write('/hello.txt', content);
});

app.command('read', async (fs: Filesystem) => {
    const content = await fs.readAsText('/hello.txt');
    console.log(content);
});

app.run();
```


## Multiple Filesystems

You can use multiple filesystems at the same time. To do so you register them with `provideNamedFilesystem('name', ...)` and receive the Filesystem instance with 
`NamedFilesystem<'name'>`.

```typescript
import { App } from '@deepkit/app';
import { NamedFilesystem, FilesystemLocalAdapter, provideNamedFilesystem } from '@deepkit/filesystem';

type PrivateFilesystem = NamedFilesystem<'private'>;
type PublicFilesystem = NamedFilesystem<'public'>;

const app = new App({
    providers: [
        provideNamedFilesystem('private', new FilesystemLocalAdapter({root: '/tmp/dir1'})),
        provideNamedFilesystem('public', new FilesystemLocalAdapter({root: '/tmp/dir2'})),
    ]
});

app.command('write', async (content: string, fs: PublicFilesystem) => {
    await fs.write('/hello.txt', content);
});

app.command('read', async (fs: PublicFilesystem) => {
    const content = await fs.readAsText('/hello.txt');
    console.log(content);
});

app.run();
```

## Configuration

It's often useful to configure an adapter via configuration options. For example, you might want to configure the root directory of the local adapter
or credentials for the AWS S3 or Google Storage adapter.

To do so, you can use [Configuration Injection](https://deepkit.io/en/documentation/app/configuration.md).

```typescript
import { App } from '@deepkit/app';
import { Filesystem, FilesystemLocalAdapter, provideFilesystem } from '@deepkit/filesystem';

class MyConfig {
    fsRoot: string = '/tmp';
}

const app = new App({
    config: MyConfig,
    providers: [
        provideFilesystem(
            (config: MyConfig) => new FilesystemLocalAdapter({root: config.fsRoot})
        ),
    ]
});

app.loadConfigFromEnv({prefix: 'APP_'})
app.run();
```

---

Source: https://deepkit.io/en/documentation/filesystem/local

# Local Filesystem

The local filesystem adapter is one of the most common filesystems and provides access to the filesystem on which the application is running.

It is part of `@deepkit/filesystem` and uses the `fs/promises` API of Node under the hood, so not additional installation is required.

## Usage

```typescript
import { FilesystemLocalAdapter, Filesystem } from '@deepkit/filesystem';

const adapter = new FilesystemLocalAdapter({ root: '/path/to/files' });
const filesystem = new Filesystem(adapter);
```

Here the `root` option is the root directory of the filesystem. All paths are relative to this root.

```typescript
// reads the file /path/to/files/hello.txt
const content: string = await filesystem.readAsText('/hello.txt');
```

## Permissions

You can configure what permissions the filesystem should use when creating files and directories. Each category (file, directory) can be configured separately into two visibilities: `public` and `private`.

```typescript
const adapter = new FilesystemLocalAdapter({
    root: '/path/to/files',
    permissions: {
        file: {
            public: 0o644,
            private: 0o600,
        },
        directory: {
            public: 0o755,
            private: 0o700,
        }
    }
});


const filesystem = new Filesystem(adapter);

filesystem.write('/hello-public.txt', 'hello world', 'public');
filesystem.write('/hello-private.txt', 'hello world', 'private');
```

Here the file `/hello-public.txt` will be created with the permissions `0o644` and `/hello-private.txt` with `0o600`.

---

Source: https://deepkit.io/en/documentation/filesystem/memory

# Memory Filesystem

For the memory filesystem, the filesystem is stored in memory. This means that the filesystem is not persistent and will be lost when the application is exited.
This is useful especially for testing purposes.

It is part of `@deepkit/filesystem`, so not additional installation is required.

## Usage

```typescript
import { FilesystemMemoryAdapter, Filesystem } from '@deepkit/filesystem';

const adapter = new FilesystemMemoryAdapter();
const filesystem = new Filesystem(adapter);
```

---

Source: https://deepkit.io/en/documentation/filesystem/database

# Database Filesystem

This adapter allows you to use an Database ORM as filesystem backend. This means all files and folders are stored in the database.

```sh
npm install @deepkit/filesystem-database @deepkit/orm
```

## Usage

```typescript
import { Filesystem } from '@deepkit/filesystem';
import { FilesystemDatabaseAdapter } from '@deepkit/filesystem-database';

const database = new Database(new MemoryDatabaseAdapter());
// const database = new Database(new PostgresDatabaseAdapter());
// const database = new Database(new MongoDatabaseAdapter());
// const database = new Database(new MysqlDatabaseAdapter());
// const database = new Database(new SQLiteDatabaseAdapter());

const adapter = new FilesystemDatabaseAdapter({ database });
const filesystem = new Filesystem(adapter);
```

---

Source: https://deepkit.io/en/documentation/filesystem/aws-s3

# AWS S3 Filesystem

The AWS S3 filesystem adapter allows you to use the AWS S3 service as Deepkit Filesystem.

It is part of `@deepkit/filesystem-aws-s3` which needs to be installed separately.

```sh
npm install @deepkit/filesystem-aws-s3
```

## Usage

```typescript
import { Filesystem } from '@deepkit/filesystem';
import { FilesystemAwsS3Adapter } from '@deepkit/filesystem-aws-s3';

const adapter = new FilesystemAwsS3Adapter({
    bucket: 'my-bucket',
    path: 'starting-path/', //optional
    region: 'eu-central-1',
    acccessKeyId: '...',
    secretAccessKey: '...'
});
const filesystem = new Filesystem(adapter);
```

Note: You should not store your credentials in the code directly. Instead, use environment variables or [App Configuration](https://deepkit.io/en/documentation/filesystem/app.md#configuration).

This adapter uses the S3 client of [@aws-sdk/client-s3](https://npmjs.com/package/@aws-sdk/client-s3). 
All its configuration options can be passed to the adapter constructor.

## Permissions

You can configure what visibility a file has when it is created.

```typescript
const filesystem = new Filesystem(adapter);

filesystem.write('/hello-public.txt', 'hello world', 'public');
filesystem.write('/hello-private.txt', 'hello world', 'private');
```

The file `/hello-public.txt` will be created with the ACL `public-read` and can be read by anyone using its URL. The url can be retrieved using `filesystem.publicUrl`.

```typescript
const url = filesystem.publicUrl('/hello-public.txt');
// https://my-bucket.s3.eu-central-1.amazonaws.com/starting-path/hello-public.txt
```

To use the visibility you have to enable object-based ACL in your S3 bucket.

---

Source: https://deepkit.io/en/documentation/filesystem/ftp

# FTP Filesystem

This adapter allows you to use an FTP server as filesystem.

It is part of `@deepkit/filesystem-ftp` which needs to be installed separately.

```sh
npm install @deepkit/filesystem-ftp
```

## Usage

```typescript
import { Filesystem } from '@deepkit/filesystem';
import { FilesystemFtpAdapter } from '@deepkit/filesystem-ftp';

const adapter = new FilesystemFtpAdapter({
    root: 'folder',
    host: 'localhost',
    port: 21,
    username: 'user',
    password: 'password',
});
const filesystem = new Filesystem(adapter);
```

Note: You should not store your credentials in the code directly. Instead, use environment variables or [App Configuration](https://deepkit.io/en/documentation/filesystem/app.md#configuration).

## Permissions

If the FTP server is running in a Unix environment, you can set the permissions of the files and folders using the `permissions` option just like with the [local filesystem adapter](https://deepkit.io/en/documentation/filesystem/local.md).

```typescript
const adapter = new FilesystemFtpAdapter({
    // ...
    permissions: {
        file: {
            public: 0o644,
            private: 0o600,
        },
        directory: {
            public: 0o755,
            private: 0o700,
        }
    }
});


const filesystem = new Filesystem(adapter);

filesystem.write('/hello-public.txt', 'hello world', 'public');
filesystem.write('/hello-private.txt', 'hello world', 'private');
```

Here the file `/hello-public.txt` will be created with the permissions `0o644` and `/hello-private.txt` with `0o600`.

---

Source: https://deepkit.io/en/documentation/filesystem/sftp

# sFTP (SSH) Filesystem

This adapter allows you to use an sFTP (SSH) server as filesystem.

It is part of `@deepkit/filesystem-sftp` which needs to be installed separately.

```sh
npm install @deepkit/filesystem-sftp
```

## Usage

```typescript
import { Filesystem } from '@deepkit/filesystem';
import { FilesystemSftpAdapter } from '@deepkit/filesystem-sftp';

const adapter = new FilesystemSftpAdapter({
    root: 'folder',
    host: 'localhost',
    port: 22,
    username: 'user',
    password: 'password',
});
const filesystem = new Filesystem(adapter);
```

Note: You should not store your credentials in the code directly. Instead, use environment variables or [App Configuration](https://deepkit.io/en/documentation/filesystem/app.md#configuration).

This adapter uses the sFTP client of [ssh2-sftp-client](https://npmjs.com/package/ssh2-sftp-client). All its configuration options can be passed to the adapter constructor.

## Permissions

If the FTP server is running in a Unix environment, you can set the permissions of the files and folders using the `permissions` option just like with the [local filesystem adapter](https://deepkit.io/en/documentation/filesystem/local.md).

```typescript
const adapter = new FilesystemFtpAdapter({
    // ...
    permissions: {
        file: {
            public: 0o644,
            private: 0o600,
        },
        directory: {
            public: 0o755,
            private: 0o700,
        }
    }
});


const filesystem = new Filesystem(adapter);

filesystem.write('/hello-public.txt', 'hello world', 'public');
filesystem.write('/hello-private.txt', 'hello world', 'private');
```

Here the file `/hello-public.txt` will be created with the permissions `0o644` and `/hello-private.txt` with `0o600`.

---

Source: https://deepkit.io/en/documentation/filesystem/google-storage

# Google Storage Filesystem

This adapter allows you to use Google Storage as filesystem.

It is part of `@deepkit/filesystem-google` which needs to be installed separately.

```sh
npm install @deepkit/filesystem-google
```

## Usage

```typescript
import { Filesystem } from '@deepkit/filesystem';
import { FilesystemGoogleAdapter } from '@deepkit/filesystem-google';

const adapter = new FilesystemGoogleAdapter({
    bucket: 'my-bucket',
    path: 'starting-path/', //optional
    projectId: '...',
    keyFilename: 'path/to/service-account-key.json'
});
const filesystem = new Filesystem(adapter);
```

Note: You should not store your credentials in the code directly. Instead, use environment variables or [App Configuration](https://deepkit.io/en/documentation/filesystem/app.md#configuration).

This adapter uses the Google Storage client of [@google-cloud/storage](https://npmjs.com/package/@google-cloud/storage).
All its configuration options can be passed to the adapter constructor.

## Permissions

You can configure what visibility a file has when it is created.

```typescript
const filesystem = new Filesystem(adapter);

filesystem.write('/hello-public.txt', 'hello world', 'public');
filesystem.write('/hello-private.txt', 'hello world', 'private');
```

The file `/hello-public.txt` will be created with the ACL `public: true` and can be read by anyone using its URL. The url can be retrieved using `filesystem.publicUrl`.

```typescript
const url = filesystem.publicUrl('/hello-public.txt');
// https://storage.googleapis.com/my-bucket/starting-path/hello-public.txt
```

To use the visibility you have to enable object-based ACL in your Google Storage bucket.

---

Source: https://deepkit.io/en/documentation/broker

# Deepkit Broker

Deepkit Broker is a high-performance abstraction for message queues, message bus, event bus, pub/sub, key/value store, cache, and atomic operations. All in the spirit of type-safety with automatic serialization and validation, high-performance, and scalability. 

Deepkit Broker is a client and a server in one. It can be used as a standalone server, or as a client to connect to other Deepkit Broker servers. It's designed to be used in a microservice architecture, but can also be used in a monolith application.

The client uses an adapter pattern to support different backends. You can use the same code with different backends, or even use multiple backends at the same time.

Currently, there are 3 adapters available. One is the default `BrokerDeepkitAdapter` which communicates with the Deepkit Broker server and comes with Deepkit Broker out of the box (including the server). 
The second is `BrokerRedisAdapter` in [@deepkit/broker-redis](https://deepkit.io/en/documentation/package/broker-redis) which communicates with a Redis server. The third is `BrokerMemoryAdapter` which is an in-memory adapter for testing purposes.

## Installation

Deepkit Broker is installed and activated per default when [Deepkit Framework](https://deepkit.io/en/documentation/framework.md) is used. Otherwise, you can install it via:

```bash
npm install @deepkit/broker
```

## Broker Classes

Deepkit Broker provides these main broker classes: 

- **BrokerCache** - L2 cache abstraction with cache invalidation 
- **BrokerBus** - Message bus (Pub/Sub)
- **BrokerQueue** - Queue system
- **BrokerLock** - Distributed lock
- **BrokerKeyValue** - Key/Value store

These classes are designed to take a broker adapter to communicate with a broker server in a type-safe way.

```typescript
import { BrokerBus, BrokerMemoryAdapter } from '@deepkit/broker';

const bus = new BrokerBus(new BrokerMemoryAdapter());
const channel = bus.channel<{ foo: string }>('my-channel-name');
await channel.subscribe((message) => {
  console.log('received message', message);
});

await channel.publish({ foo: 'bar' });
```

The FrameworkModule provides and registers the default adapter and connects to Deepkit Broker server, which runs per default in the same process.

Thanks to runtime types and the call `channel<Type>('my-channel-name');` everything is type-safe and the message can be validated and serialized automatically in the adapter directly.
The default implementation `BrokerDeepkitAdapter` handles this automatically for you (and uses BSON for serialization).

Note that each broker class has its own adapter interface, so you can implement only the methods you need. The `BrokerDeepkitAdapter` implements all of these interfaces and can be used in all broker APIs.

## Application Integration

To use these classes in a Deepkit application with dependency injection, you can use the `FrameworkModule` which provides several things:

- a default adapter for the broker server
- the broker server itself (and starts it automatically)
- and registers all broker classes as providers

The `FrameworkModule` provides a default broker adapter for the configured broker server based on the given configuration.
It also registers providers for all the broker classes, so you can inject them (e.g. BrokerBus) into your services and provider factories directly.

```typescript
// in an extra file, e.g. broker-channels.ts
type MyBusChannel = BrokerBusChannel<MyMessage>;

const app = new App({
  providers: [
    Service,
    provide<MyBusChannel>((bus: BrokerBus) => bus.channel<MyMessage>('my-channel-name')),
  ],
  imports: [new FrameworkModule({
    broker: {
      // If startOnBootstrap is true, the broker server starts at this address. Unix socket path or host:port combination
      listen: 'localhost:8811', // or 'var/broker.sock';
      // If a different broker server should be used, this is its address. Unix socket path or host:port combination.
      host: 'localhost:8811', //or 'var/broker.sock';
      // Automatically starts a single broker in the main process. Disable it if you have a custom broker node.
      startOnBootstrap: true,
    },
  })],
});
```

You can then inject the broker derived classes (or the broker class directly) into your services:

```typescript
import { MyBusChannel } from './broker-channels.ts';

class Service {
  constructor(private bus: MyBusChannel) {
  }

  async addUser() {
    await this.bus.publish({ foo: 'bar' });
  }
}
```

It's always a good idea to create a derived type for your channels (like above with `MyBusChannel`), so you can easily inject them into your services.
Otherwise, you'd have to inject `BrokerBus` and call `channel<MyMessage>('my-channel-name')` every time you need it, which is error-prone and not DRY. 

Almost all broker classes have this kind of derivation, so you can easily define them in one place and use them everywhere. See the appropriate broker class documentation for more information.

## Custom Adapter

If you need a custom adapter, you can create your own adapter by implementing one or more of the following interfaces from `@deepkit/broker`:

```typescript
export type BrokerAdapter = BrokerAdapterCache & BrokerAdapterBus & BrokerAdapterLock & BrokerAdapterQueue & BrokerAdapterKeyValue;
```

```typescript
import { BrokerAdapterBus, BrokerBus, Release } from '@deepkit/broker';
import { Type } from '@deepkit/type';

class MyAdapter implements BrokerAdapterBus {
  disconnect(): Promise<void> {
    // implement: disconnect from broker server
  }
  async publish(name: string, message: any, type: Type): Promise<void> {
    // implement: send message to broker server, name is 'my-channel-name', message is { foo: 'bar' }
  }
  async subscribe(name: string, callback: (message: any) => void, type: Type): Promise<Release> {
    // implemenet: subscribe to broker server, name is 'my-channel-name'
  }
}

// or BrokerDeepkitAdapter for the default adapter
const adapter = new MyAdapter;
const bus = new BrokerBus(adapter);

```

## Broker Server

The Broker server starts automatically per default as soon as you import the `FrameworkModule` and run the `server:start` command.
All Broker classes are configured per default to connect to this server.

In a production environment, you would run the broker server in a separate process, or on a different machine. 
Instead of doing `server:start` you would start the broker server with `server:broker:start`.

If you have a lot of traffic and need scalability, you should use the [redis adapter](https://deepkit.io/en/documentation/package/broker-redis.md) instead. It is more complicated to set up, 
since you have to run a Redis server, but it is more performant and can handle more traffic.

```bash
ts-node app.ts server:broker:start
```

This starts the server on the host configured via for example `new FrameworkModule({broker: {listen: 'localhost:8811'}})`.
You could change the address also via environment variables if you enabled `app.loadConfigFromEnv({prefix: 'APP_', namingStrategy: 'upper'});`:

```bash
APP_FRAMEWORK_BROKER_LISTEN=localhost:8811 ts-node app.ts server:broker:start
```

If you start the server manually, make sure to disable automatic broker server start via `startOnBootstrap: false` in your application configuration.

---

Source: https://deepkit.io/en/documentation/broker/cache

# Broker Cache

Deepkit Broker Cache class is a multi-level (2 levels) cache that keeps a volatile local cache in memory and only fetches data from the broker server
if the data is not in the cache, stale, or was invalidated. This allows to use cache for very high performance and low latency data fetching.

The cache is designed to be type-safe and automatically serializes and deserializes data (using BSON). It also supports cache invalidation and cache clearing.
The implementation makes sure that per process the cache is rebuilt only once, even if multiple requests are trying to access the same cache item at the same time.

The data is not persisted on the server, but only kept in memory. If the server restarts, all data is lost.

## Usage

Make sure to read the Getting started page to learn how to properly set up your application so BrokerCache is available in the dependency injection container.

The cache abstraction in Deepkit Broker is very different to a simple key/value store. It works by defining a cache name and a builder function that is called automatically when the cache is empty or stale. This builder function is responsible to build the data that is then stored in the cache.

```typescript
import { BrokerCache, BrokerCacheItem } from '@deepkit/broker';

const cache = new BrokerCache(adapter);

const cacheItem = cache.item('my-cache', async () => {
  // this is the builder function that is called when 
  // the cache is empty or stale
  return 'hello world';
});


// check if cache is stale or empty
await cacheItem.exists();

// get the data from the cache or fetch it from the broker server
// if the cache is empty or stale, the builder function is called
// and result returned and send to the broker server.
const topUsers = await cacheItem.get();

// invalidate the cache so next get() call will 
// call the builder function again.
// Clears the local cache and server cache.
await cacheItem.invalidate();

// manually set data in the cache
await cacheItem.set(xy);
```

## App Usage

A full example of how to use the BrokerCache in your application.
The class is automatically available in the dependency injection container if you import the `FrameworkModule`.
See the Getting started page for more information.

```typescript
import { BrokerCache, BrokerCacheItem } from '@deepkit/broker';
import { FrameworkModule } from '@deepkit/framework';

// it's a good to have these types defined in a common file so you can reuse them
// and inject them into your services
type MyCacheItem = BrokerCacheItem<User[]>;

function createMyCache(cache: BrokerCache, database: Database) {
  return cache.item<User[]>('top-users', async () => {
    // this is the builder function that is called when 
    // the cache is empty or stale
    return await database.query(User)
      .limit(10).orderBy('score').find();
  });
}

class Service {
  constructor(private cacheItem: MyCacheItem) {
  }

  async getTopUsers() {
    return await this.cacheItem.get();
  }
}

const app = new App({
  providers: [
    Service,
    Database,
    provide<MyCacheItem>(createMyCache),
  ],
  imports: [
    new FrameworkModule(),
  ],
});

const cacheItem = app.get<MyCacheItem>();

// get the data from the cache or fetch it from the broker server
const topUsers = await cacheItem.get();
```

---

Source: https://deepkit.io/en/documentation/broker/message-bus

# Broker Bus

Deepkit Message Bus is a message bus system (Pub/Sub, distributed event system) that allows you to send messages or events between different parts of your application.

It can be used in microservices, monoliths, or any other kind of application. Perfectly suited for event-driven architectures.  

It is different to the Deepkit Event system, which is used for in-process events. The Broker Bus is used for events that need to be sent to other processes or servers. Broker Bus is also perfectly suited when you want to communicate between several workers that were automatically started by FrameworkModule, e.g. `new FrameworkModule({workers: 4})`.

The system is designed to be type-safe and automatically serializes and deserializes messages (using BSON). If you add [validation](https://deepkit.io/en/documentation/runtime-types/validation.md) to your message types, it will also validate the messages before sending and after receiving them. This ensures that the messages are always in the correct format and contain the expected data.

## Usage

```typescript
import { BrokerBus } from '@deepkit/broker';

const bus = new BrokerBus(adapter);

// move this type to a shared file
type UserEvent = { type: 'user-created', id: number } | { type: 'user-deleted', id: number };

const channel = bus.channel<Events>('user-events');

await channel.subscribe((event) => {
  if (event.type === 'user-created') {
    console.log('User created', event.id);
  } else if (event.type === 'user-deleted') {
    console.log('User deleted', event.id);
  }
});

await channel.publish({ type: 'user-created', id: 1 });
```

By defining a name and a type for the channel, you can ensure that only messages of the correct type are sent and received.
The data is automatically serialized and deserialized (using BSON).

## App Usage

A full example of how to use the BrokerBus in your application.
The class is automatically available in the dependency injection container if you import the `FrameworkModule`.
See the Getting started page for more information.

### Subject

The default approach to send and listen to messages is using rxjs `Subject` type. Its `subscribe` and `next` methods allow you to send and receive messages in a type-safe way. All Subject instances are managed by the broker and once the Subject is garbage collected, the subscription is removed from the broker backend (e.g. Redis).

Override BrokerBus' `BusBrokerErrorHandler` to handle failures in publishing or subscribing to messages.

This approach nicely decouples your business code with the broker server and allows you to use the same code in a test environment without a broker server.

```typescript
import { BrokerBus, BrokerBusChannel, provideBusSubject } from '@deepkit/broker';
import { FrameworkModule } from '@deepkit/framework';
import { Subject } from 'rxjs';

// move this type to a shared file
type MyChannel = Subject<{
    id: number;
    name: string;
}>;

class Service {
    // MyChannel is not a singleton, but a new instance is created for each request.
    // Its lifetime is monitored by the framework and once the subject is garbage collected, 
    // the subscription is removed from the broker backend (e.g. Redis).
    constructor(private channel: MyChannel) {
        this.channel.subscribe((message) => {
            console.log('received message', message);
        });
    }

    update() {
        this.channel.next({ id: 1, name: 'Peter' });
    }
}

@rpc.controller('my-controller')
class MyRpcController {
    constructor(private channel: MyChannel) {
    }

    @rpc.action()
    getChannelData(): MyChannel {
        return this.channel;
    }
}

const app = new App({
    controllers: [MyRpcController],
    providers: [
        Service,
        provideBusSubject<MyChannel>('my-channel'),
    ],
    imports: [
        new FrameworkModule(),
    ],
});
```

### BusChannel 

If you need confirmation of the message being sent and want to handle errors in each case, you can use the `BrokerBusChannel` type. It's `subscribe` and `publish` methods return a promise.

```typescript
import { BrokerBus, BrokerBusChannel, provideBusChannel } from '@deepkit/broker';
import { FrameworkModule } from '@deepkit/framework';

// move this type to a shared file
type MyChannel = BrokerBusChannel<{
    id: number;
    name: string;
}>;

class Service {
    constructor(private channel: MyChannel) {
        this.channel.subscribe((message) => {
            console.log('received message', message);
        }).catch(e => {
            console.error('Error while subscribing', e);
        });
    }

    async update() {
        await this.channel.publish({ id: 1, name: 'Peter' });
    }
}

const app = new App({
    providers: [
        Service,
        provideBusChannel<MyChannel>('my-channel'),
    ],
    imports: [
        new FrameworkModule(),
    ],
});
```

---

Source: https://deepkit.io/en/documentation/broker/message-queue

# Broker Queue

Deepkit Message Queue is a message queue system that allows you to send messages to the queue server and have workers process them.

The system is designed to be type-safe and automatically serializes and deserializes messages (using BSON).

The data is persisted on the server, so even if the server crashes, the data is not lost.

## Usage

```typescript
import { BrokerQueue, BrokerQueueChannel } from '@deepkit/broker';

const queue = new BrokerQueue(adapter);

type User = { id: number, username: string };

const registrationChannel = queue.channel<User>('user/registered', {
  process: QueueMessageProcessing.exactlyOnce,
  deduplicationInterval: '1s',
});

// a worker consumes the messages.
// this is usually done in a separate process.
await registrationChannel.consume(async (user) => {
  console.log('User registered', user);
  // if the worker crashes here, the message is not lost.
  // it will be automatically redelivered to another worker.
  // if this callback returns without an error, the message is 
  // marked as processed and eventually removed.
});

// the application sending the message
await registrationChannel.produce({ id: 1, username: 'Peter' });
```

## App Usage

A full example of how to use the BrokerQueue in your application.
The class is automatically available in the dependency injection container if you import the `FrameworkModule`.
See the Getting started page for more information.

To utilize the queue systems the most, it is recommended to start several workers that consume the messages.
You would write a separate `App` that is different to the main application that might have http routes etc.

You share common services via a shared app module. Channel definitions are shared via the rest of the application in a common file.

```typescript
// file: channels.ts

export type RegistrationChannel = BrokerQueueChannel<User>;
export const registrationChannelProvider = provide<RegistrationChannel>((queue: BrokerQueue) => queue.channel<User>('user/registered', {
  process: QueueMessageProcessing.exactlyOnce,
  deduplicationInterval: '1s',
}));
```

```typescript
// file: worker.ts
import { RegistrationChannel, registrationChannelProvider } from './channels';

async function consumerCommand(
  channel: RegistrationChannel, 
  database: Database) {

  await channel.consume(async (user) => {
    // do something with the user,
    // maybe store information, send emails, etc.
  });

  // the connection to the broker keeps the process alive.
}

const app = new App({
  providers: [
    Database,
    registrationChannelProvider,
  ],
  imports: [
    new FrameworkModule({}),
  ],
});

app.command('consumer', consumerCommand);

// start the worker command above directly
void app.run('consumer');
```

And in your application you produce messages like this:

```typescript
// file: app.ts
import { RegistrationChannel, registrationChannelProvider } from './channels';

class Service {
  constructor(private channel: RegistrationChannel) {
  }

  async registerUser(user: User) {
    await this.channel.produce(user);
  }
}

const app = new App({
  providers: [
    Service,
    registrationChannelProvider,
  ],
  imports: [
    new FrameworkModule({}),
  ],
});

void app.run();
```

---

Source: https://deepkit.io/en/documentation/broker/atomic-locks

# Broker Atomic Locks

Deepkit Broker Locks is a simple way to create atomic locks across multiple processes or machines. 

It's a simple way to ensure that only one process can execute a certain code block at a time.

## Usage

```typescript
import { BrokerLock } from '@deepkit/broker';

const lock = new BrokerLock(adapter);

// lock is alive for 60 seconds.
// acquisition timeout is 10 seconds.
const myLock = lock.item('my-lock', { ttl: '60s', timeout: '10s' });

async function criticalSection() {
  // Holds the lock until the function is done.
  // cleans up the lock automatically, even if the function throws an error.
  await using hold = await lock1.hold();
}
```

The lock supports [Explicit Resource Management](https://github.com/tc39/proposal-explicit-resource-management), which means you don't have to use a try-catch block to ensure the lock is released properly.

To manually acquire and release a lock, you can use the `acquire` and `release` methods.

```typescript
// this blocks until the lock is acquired.
// or throws if timeout is reached
await myLock.acquire();

try {
  // do something critical
} finally {
  await myLock.release();
}
```

## App Usage

A full example of how to use the BrokerLock in your application.
The class is automatically available in the dependency injection container if you import the `FrameworkModule`.
See the Getting started page for more information.

```typescript
import { BrokerLock, BrokerLockItem } from '@deepkit/broker';
import { FrameworkModule } from '@deepkit/framework';

// move this type to a shared file
type MyCriticalLock = BrokerLockItem;

class Service {
  constructor(private criticalLock: MyCriticalLock) {
  }

  async doSomethingCritical() {
    await using hold = await this.criticalLock.hold();
    
    // do something critical,
    // lock is released automatically
  }
}

const app = new App({
  providers: [
    Service,
    provide<MyCriticalLock>((lock: BrokerLock) => lock.item('my-critical-lock', { ttl: '60s', timeout: '10s' })),
  ],
  imports: [
    new FrameworkModule(),
  ],
});
```

---

Source: https://deepkit.io/en/documentation/broker/key-value

# Broker Key-Value

Deepkit Broker Key-Value class is a simple key/value store abstraction that works with the broker server. It's a simple way to store and retrieve data from the broker server.

There is no local caching implemented. All `get` calls are real network requests to the broker server, every time. To avoid this, use the Broker Cache abstraction.

The data is not persisted on the server, but only kept in memory. If the server restarts, all data is lost.

## Usage

```typescript
import { BrokerKeyValue } from '@deepkit/broker';

const keyValue = new BrokerKeyValue(adapter, {
  ttl: '60s', // time to live for each key. 0 means no ttl (default).
});

const item = keyValue.item<number>('key1');

await item.set(123);
console.log(await item.get()); //123

await item.remove();
```

The data is automatically serialized and deserialized using BSON based on the given type.

The methods `set` and `get` can also be called directly on the `BrokerKeyValue` instance,
but has the disadvantage that you have to pass the key and type every time.

```typescript
await keyValue.set<number>('key1', 123);
console.log(await keyValue.get<number>('key1')); //123
```

## Increment

The `increment` method allows you to atomically increment the value of a key by a given amount.

Note that this creates its own storage entry on the server and is not compatible with `set` or `get`. 

```typescript

const activeUsers = keyValue.item<number>('activeUsers');

// Increment by 1 atomically
await activeUsers.increment(1);

await activeUsers.increment(-1);

// The only way to get the current value is to call increment with 0
const current = await activeUsers.increment(0);

// removes the entry
await activeUsers.remove();
```

## App Usage

A full example of how to use the BrokerKeyValue in your application.
The class is automatically available in the dependency injection container if you import the `FrameworkModule`.
See the Getting started page for more information.

```typescript
import { BrokerKeyValue, BrokerKeyValueItem } from '@deepkit/broker';
import { FrameworkModule } from '@deepkit/framework';

// move this type to a shared file
type MyKeyValueItem = BrokerKeyValueItem<User[]>;

class Service {
  constructor(private keyValueItem: MyKeyValueItem) {
  }

  async getTopUsers(): Promise<User[]> {
    // Might be undefined. You have to handle this case.
    // Use Broker Cache if you want to avoid this.
    return await this.keyValueItem.get();
  }
}

const app = new App({
  providers: [
    Service,
    provide<MyKeyValueItem>((keyValue: BrokerKeyValue) => keyValue.item<User[]>('top-users')),
  ],
  imports: [
    new FrameworkModule(),
  ],
});
```

---

Source: https://deepkit.io/en/documentation/http

# HTTP

Processing HTTP requests is one of the most well-known tasks for a server. It converts an input (HTTP request) into an output (HTTP response) and performs a specific task. A client can send data to the server via an HTTP request in a variety of ways, which must be read and handled correctly. In addition to the HTTP body, HTTP query or HTTP header values are also possible. How data is actually processed depends on the server. It is the server that defines where and how the values are to be sent by the client.

The top priority here is not only to correctly execute what the user expects, but to correctly convert (deserialize) and validate any input from the HTTP request.

The pipeline through which an HTTP request passes on the server can be varied and complex. Many simple HTTP libraries pass only the HTTP request and the HTTP response for a given route, and expect the developer to process the HTTP response directly. A middleware API allows the pipeline to be extended as needed.

_Express Example_

```typescript
const http = express();
http.get('/user/:id', (request, response) => {
    response.send({id: request.params.id, username: 'Peter' );
});
```

This is very well tailored for simple use cases, but quickly becomes confusing as the application grows, since all inputs and outputs must be manually serialized or deserialized and validated. Also, consideration must be given to how objects and services such as a database abstraction can be obtained from the application itself. It forces the developer to put an architecture on top of it that maps these mandatory functionalities.

Deepkit's HTTP Library instead leverages the power of TypeScript and Dependency Injection. Serialization/Deserialization and validation of any values happen automatically based on the defined types. It also allows defining routes either via a functional API as in the example above or via controller classes to cover the different needs of an architecture.

It can be used either with an existing HTTP server like Node's `http` module or with the Deepkit framework. Both API variants have access to the dependency injection container and can thus conveniently retrieve objects such as a database abstraction and configurations from the application.

## Example Functional API

```typescript
import { Positive } from '@deepkit/type';
import { http, HttpRouterRegistry } from '@deepkit/http';
import { FrameworkModule } from "@deepkit/framework";

//Functional API
const app = new App({
    imports: [new FrameworkModule()]
});
const router = app.get(HttpRouterRegistry);

router.get('/user/:id', (id: number & Positive, database: Database) => {
    //id is guaranteed to be a number and positive.
    //database is injected by the DI Container.
    return database.query(User).filter({ id }).findOne();
});

app.run();
```

## Class Controller API

```typescript
import { Positive } from '@deepkit/type';
import { http, HttpRouterRegistry } from '@deepkit/http';
import { FrameworkModule } from "@deepkit/framework";
import { User } from "discord.js";

//Controller API
class UserController {
    constructor(private database: Database) {
    }

    @http.GET('/user/:id')
    user(id: number & Positive) {
        return this.database.query(User).filter({ id }).findOne();
    }
}

const app = new App({
    controllers: [UserController],
    imports: [new FrameworkModule()]
});
```

---

Source: https://deepkit.io/en/documentation/http/getting-started

# Getting Started

Since Deepkit HTTP is based on Runtime Types, it is necessary to have Runtime Types already installed correctly. See [Runtime Type Installation](https://deepkit.io/en/documentation/runtime-types/getting-started.md).

If this is done successfully, `@deepkit/app` can be installed or the Deepkit framework which already uses the library under the hood.

```sh
npm install @deepkit/http
```

Note that `@deepkit/http` for the controller API is based on TypeScript annotations and this feature must be enabled accordingly with `experimentalDecorators` once the controller API is used.
If you don't use classes, you don't need to enable this feature.

_File: tsconfig.json_

```json
{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "es6",
    "moduleResolution": "node",
    "experimentalDecorators": true
  },
  "reflection": true
}
```

Once the library is installed, the API of it can be used directly.

## Functional API

The functional API is based on functions and can be registered via the router registry, which can be obtained via the DI container of the app.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { HttpRouterRegistry } from '@deepkit/http';

const app = new App({
    imports: [new FrameworkModule]
});

const router = app.get(HttpRouterRegistry);

router.get('/', () => {
    return "Hello World!";
});

app.run();
```

Once modules are used, functional routes can also be provided dynamically by modules.

```typescript
import { App, createModuleClass } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { HttpRouterRegistry } from '@deepkit/http';

class MyModule extends createModuleClass({}) {
  override process() {
    this.configureProvider<HttpRouterRegistry>(router => {
      router.get('/', () => {
        return "Hello World!";
      });
    });
  }
}

const app = new App({
  imports: [new FrameworkModule, new MyModule]
});
```

See [Framework Modules](https://deepkit.io/en/documentation/app/modules), to learn more about App Modules.

## Controller API

The controller API is based on classes and can be registered via the App-API under the option `controllers`.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { http } from '@deepkit/http';

class MyPage {
    @http.GET('/')
    helloWorld() {
        return "Hello World!";
    }
}

new App({
    controllers: [MyPage],
    imports: [new FrameworkModule]
}).run();
```

Once modules are used, controllers can also be provided by modules.

```typescript
import { App, createModuleClass } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { http } from '@deepkit/http';

class MyPage {
  @http.GET('/')
  helloWorld() {
    return "Hello World!";
  }
}

class MyModule extends createModuleClass({}) {
  override process() {
    this.addController(MyPage);
  }
}

const app = new App({
  imports: [new FrameworkModule, new MyModule]
});
```

To provide controllers dynamically (depending on the configuration option, for example), the `process` hook can be used.

```typescript
class MyModuleConfiguration {
    debug: boolean = false;
}

class MyModule extends createModuleClass({
    config: MyModuleConfiguration
}) {
    override process() {
        if (this.config.debug) {
            class DebugController {
                @http.GET('/debug/')
                root() {
                    return 'Hello Debugger';
                }
            }
            this.addController(DebugController);
        }
    }
}
```

See [Framework Modules](https://deepkit.io/en/documentation/app/modules), to learn more about App Modules.

## HTTP Server

If Deepkit Framework is used, an HTTP server is already built in. However, the HTTP library can also be used with its own HTTP server without using the Deepkit framework.

```typescript
import { Server } from 'http';
import { HttpRequest, HttpResponse } from '@deepkit/http';

const app = new App({
    controllers: [MyPage],
    imports: [new HttpModule]
});

const httpKernel = app.get(HttpKernel);

new Server(
    { IncomingMessage: HttpRequest, ServerResponse: HttpResponse, },
    ((req, res) => {
        httpKernel.handleRequest(req as HttpRequest, res as HttpResponse);
    })
).listen(8080, () => {
    console.log('listen at 8080');
});
```

## HTTP Client

todo: fetch API, validation, und cast.

## Route Names

Routes can be given a unique name that can be referenced when forwarding. Depending on the API, the way a name is defined differs.

```typescript
//functional API
router.get({
    path: '/user/:id',
    name: 'userDetail'
}, (id: number) => {
    return {userId: id};
});

//controller API
class UserController {
    @http.GET('/user/:id').name('userDetail')
    userDetail(id: number) {
        return {userId: id};
    }
}
```

From all routes with a name the URL can be requested by `Router.resolveUrl()`.

```typescript
import { HttpRouter } from '@deepkit/http';
const router = app.get(HttpRouter);
router.resolveUrl('userDetail', {id: 2}); //=> '/user/2'
```

## Security

## Sessions

---

Source: https://deepkit.io/en/documentation/http/input-output

# Input & Output

The input and output of an HTTP route is the data that is sent to the server and the data that is sent back to the client. This includes the path parameters, query parameters, body, headers, and the response itself. In this chapter, we will look at how to read, deserialize, validate, and write data in an HTTP route.

## Input

All the following input variations function in the same way for both the functional and the controller API. They allow data to be read from an HTTP request in a typesafe and decoupled manner. This not only leads to significantly increased security, but also simplifies unit testing, since strictly speaking, not even an HTTP request object needs to exist to test the route.

All parameters are automatically converted (deserialized) to the defined TypeScript type and validated. This is done via Deepkit Runtime Types and its [Serialization](https://deepkit.io/en/documentation/runtime-types/serialization.md) and [Validation](https://deepkit.io/en/documentation/runtime-types/validation) features.

For simplicity, all examples with the functional API are shown below.

### Path Parameters

Path parameters are values extracted from the URL of the route. The type of the value depends on the type at the associated parameter of the function or method. The conversion is done automatically with the feature [Soft Type Conversion](https://deepkit.io/en/documentation/runtime-types/serialization#soft-type-conversion).

```typescript
router.get('/:text', (text: string) => {
    return 'Hello ' + text;
});
```

```sh
$ curl http://localhost:8080/galaxy
Hello galaxy
```

If a Path parameter is defined as a type other than string, it will be converted correctly.

```typescript
router.get('/user/:id', (id: number) => {
    return `${id} ${typeof id}`;
});
```

```sh
$ curl http://localhost:8080/user/23
23 number
```

Additional validation constraints can also be applied to the types.

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

router.get('/user/:id', (id: number & Positive) => {
    return `${id} ${typeof id}`;
});
```

All validation types from `@deepkit/type` can be applied. For more on this, see [HTTP Validation](#validation).

The Path parameters have `[^]+` set as a regular expression by default in the URL matching. The RegExp for this can be customized as follows:

```typescript
import { HttpRegExp } from '@deepkit/http';
import { Positive } from '@deepkit/type';

router.get('/user/:id', (id: HttpRegExp<number & Positive, '[0-9]+'>) => {
    return `${id} ${typeof id}`;
});
```

This is only necessary in exceptional cases, because often the types in combination with validation types themselves already correctly restrict possible values.

### Query Parameters

Query parameters are values from the URL after the `?` character and can be read with the `HttpQuery<T>` type. The name of the parameter corresponds to the name of the query parameter.

```typescript
import { HttpQuery } from '@deepkit/http';

router.get('/', (text: HttpQuery<number>) => {
    return `Hello ${text}`;
});
```

```sh
$ curl http://localhost:8080/\?text\=galaxy
Hello galaxy
```

Query parameters are also automatically deserialized and validated.

```typescript
import { HttpQuery } from '@deepkit/http';
import { MinLength } from '@deepkit/type';

router.get('/', (text: HttpQuery<string> & MinLength<3>) => {
    return 'Hello ' + text;
}
```

```sh
$ curl http://localhost:8080/\?text\=galaxy
Hello galaxy
$ curl http://localhost:8080/\?text\=ga
error
```

All validation types from `@deepkit/type` can be applied. For more on this, see [HTTP Validation](#validation).

Warning: Parameter values are not escaped/sanitized. Their direct return in a string in a route as HTML opens a security hole (XSS). Make sure that external input is never trusted and filtere/sanitize/convert data where necessary.

### Query Model

With a large number of query parameters, it can quickly become confusing. To bring order back in here, a model (class or interface) can be used, which summarizes all possible query parameters.

```typescript
import { HttpQueries } from '@deepkit/http';

class HelloWorldQuery {
    text!: string;
    page: number = 0;
}

router.get('/', (query: HttpQueries<HelloWorldQuery>)
{
    return 'Hello ' + query.text + ' at page ' + query.page;
}
```

```sh
$ curl http://localhost:8080/\?text\=galaxy&page=1
Hello galaxy at page 1
```

The properties in the specified model can contain all TypeScript types and validation types that `@deepkit/type` supports. See the chapter [Serialization](https://deepkit.io/en/documentation/runtime-types/serialization.md) and [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md).

### Body

For HTTP methods that allow an HTTP body, a body model can also be specified. The body content type of the HTTP request must be either `application/x-www-form-urlencoded`, `multipart/form-data` or `application/json` so that Deepkit can automatically convert this to JavaScript objects.

```typescript
import { HttpBody } from '@deepkit/type';

class HelloWorldBody {
    text!: string;
}

router.post('/', (body: HttpBody<HelloWorldBody>) => {
    return 'Hello ' + body.text;
}
```

### Header

### Stream

### Manual Validation Handling

To manually take over the validation of the body model, a special type `HttpBodyValidation<T>` can be used. It allows to receive also invalid body data and to react very specifically to error messages.

```typescript
import { HttpBodyValidation } from '@deepkit/type';

class HelloWorldBody {
    text!: string;
}

router.post('/', (body: HttpBodyValidation<HelloWorldBody>) => {
    if (!body.valid()) {
        // Houston, we got some errors.
        const textError = body.getErrorMessageForPath('text');
        return 'Text is invalid, please fix it. ' + textError;
    }

    return 'Hello ' + body.text;
})
```

As soon as `valid()` returns `false`, the values in the specified model may be in a faulty state. This means that the validation has failed. If `HttpBodyValidation` is not used and an incorrect HTTP request is received, the request would be directly aborted and the code in the function would never be executed. Use `HttpBodyValidation` only if, for example, error messages regarding the body should be manually processed in the same route.

The properties in the specified model can contain all TypeScript types and validation types that `@deepkit/type` supports. See the chapter [Serialization](https://deepkit.io/en/documentation/runtime-types/serialization.md) and [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md).

### File Upload

A special property type on the body model can be used to allow the client to upload files. Any number of `UploadedFile` can be used.

```typescript
import { UploadedFile, HttpBody } from '@deepkit/http';
import { readFileSync } from 'fs';

class HelloWordBody {
    file!: UploadedFile;
}

router.post('/', (body: HttpBody<HelloWordBody>) => {
    const content = readFileSync(body.file.path);

    return {
        uploadedFile: body.file
    };
})
```

```sh
$ curl http://localhost:8080/ -X POST -H "Content-Type: multipart/form-data" -F "file=@Downloads/23931.png"
{
    "uploadedFile": {
        "size":6430,
        "path":"/var/folders/pn/40jxd3dj0fg957gqv_nhz5dw0000gn/T/upload_dd0c7241133326bf6afddc233e34affa",
        "name":"23931.png",
        "type":"image/png",
        "lastModifiedDate":"2021-06-11T19:19:14.775Z"
    }
}
```

By default, Router saves all uploaded files to a temp folder and removes them once the code in the route has been executed. It is therefore necessary to read the file in the specified path in `path` and save it to a permanent location (local disk, cloud storage, database).

## Validation

Validation in an HTTP server is a mandatory functionality, because almost always work with data that is not trustworthy. The more places data is validated, the more stable the server is. Validation in HTTP routes can be conveniently used via types and validation constraints and is checked with a highly optimized validator from `@deepkit/type`, so there are no performance problems in this regard. It is therefore highly recommended to use these validation capabilities as well. Better one time too much, than one time too little.

All inputs such as path parameters, query parameters, and body parameters are automatically validated for the specified TypeScript type. If additional constraints are specified via types of `@deepkit/type`, these are also checked.

```typescript
import { HttpQuery, HttpQueries, HttpBody } from '@deepkit/http';
import { MinLength } from '@deepkit/type';

router.get('/:text', (text: string & MinLength<3>) => {
    return 'Hello ' + text;
}

router.get('/', (text: HttpQuery<string> & MinLength<3>) => {
    return 'Hello ' + text;
}

interface MyQuery {
    text: string & MinLength<3>;
}

router.get('/', (query: HttpQueries<MyQuery>) => {
    return 'Hello ' + query.text;
});

router.post('/', (body: HttpBody<MyQuery>) => {
    return 'Hello ' + body.text;
});
```

See [Validation](https://deepkit.io/en/documentation/runtime-types/validation.md) for more information on this.

## Output

A route can return various data structures. Some of them are handled in a special way, such as redirects and templates, and others, such as simple objects, are simply sent as JSON.

### JSON

By default, normal JavaScript values are returned to the client as JSON with the header `applicationjson; charset=utf-8`.

```typescript
router.get('/', () => {
    // will be sent as application/json
    return { hello: 'world' }
});
```

If an explicit return type is specified for the function or method, the data is serialized to JSON with the Deepkit JSON Serializer according to this type.

```typescript
interface ResultType {
    hello: string;
}

router.get('/', (): ResultType => {
    // will be sent as application/json and additionalProperty is dropped
    return { hello: 'world', additionalProperty: 'value' };
});
```

### HTML

To send HTML there are two possibilities. Either the object `HtmlResponse` or Template Engine with JSX is used.

```typescript
import { HtmlResponse } from '@deepkit/http';

router.get('/', () => {
    // will be sent as Content-Type: text/html
    return new HtmlResponse('<b>Hello World</b>');
});
```

```typescript
router.get('/', () => {
    // will be sent as Content-Type: text/html
    return <b>Hello
    World < /b>;
});
```

The template engine variant with JSX has the advantage that used variables are automatically HTML-escaped. See also [Template](https://deepkit.io/en/documentation/template.md).

### Custom Content Type

Besides HTML and JSON it is also possible to send text or binary data with a specific content type. This is done via the object `Response`.

```typescript
import { Response } from '@deepkit/http';

router.get('/', () => {
    return new Response('<title>Hello World</title>', 'text/xml');
});
```

### HTTP Errors

By throwing various HTTP errors, it is possible to immediately interrupt the processing of an HTTP request and output the corresponding HTTP status of the error.

```typescript
import { HttpNotFoundError } from '@deepkit/http';

router.get('/user/:id', async (id: number, database: Database) => {
    const user = await database.query(User).filter({ id }).findOneOrUndefined();
    if (!user) throw new HttpNotFoundError('User not found');
    return user;
});
```

By default, all errors are returned to the client as JSON. This behavior can be customized in the event system under the event `httpWorkflow.onControllerError`. See the section [HTTP Events](https://deepkit.io/en/documentation/http/events.md).

| Error class               | Status |
|---------------------------|--------|
| HttpBadRequestError       | 400    |
| HttpUnauthorizedError     | 401    |
| HttpAccessDeniedError     | 403    |
| HttpNotFoundError         | 404    |
| HttpMethodNotAllowedError | 405    |
| HttpNotAcceptableError    | 406    |
| HttpTimeoutError          | 408    |
| HttpConflictError         | 409    |
| HttpGoneError             | 410    |
| HttpTooManyRequestsError  | 429    |
| HttpInternalServerError   | 500    |
| HttpNotImplementedError   | 501    |

The error `HttpAccessDeniedError` is a special case. As soon as it is thrown, the HTTP workflow (see [HTTP Events](https://deepkit.io/en/documentation/http/events.md)) does not jump to `controllerError` but to `accessDenied`.

Custom HTTP errors can be created and thrown with `createHttpError`.

```typescript
export class HttpMyError extends createHttpError(412, 'My Error Message') {
}
```

Thrown errors in a controller action are handled by the HTTP workflow event `onControllerError`. The default implementation is to return a JSON response with the error messag and status code. This can be customized by listening to this event and returning a different response.

```typescript
import { httpWorkflow } from '@deepkit/http';

new App()
    .listen(httpWorkflow.onControllerError, (event) => {
        if (event.error instanceof HttpMyError) {
            event.send(new Response('My Error Message', 'text/plain').status(500));
        } else {
            //for all other errors, return a generic error message
            event.send(new Response('Something went wrong. Sorry about that.', 'text/plain').status(500));
        }
    })
    .listen(httpWorkflow.onAccessDenied, (event) => {
        event.send(new Response('Access denied. Try to login first.', 'text/plain').status(403));
    });
```

### Additional headers

To modify the header of an HTTP response, additional methods can be called on the `Response`, `JSONResponse`, and `HTMLResponse` objects.

```typescript
import { Response } from '@deepkit/http';

router.get('/', () => {
    return new Response('Access Denied', 'text/plain')
        .header('X-Reason', 'unknown')
        .status(403);
});
```

### Redirect

To return a 301 or 302 redirect as a response, `Redirect.toRoute` or `Redirect.toUrl` can be used.

```typescript
import { Redirect } from '@deepkit/http';

router.get({ path: '/', name: 'homepage' }, () => {
    return <b>Hello
    World < /b>;
});

router.get({ path: '/registration/complete' }, () => {
    return Redirect.toRoute('homepage');
});
```

The `Redirect.toRoute` method uses the route name here. How to set a route name can be seen in the section [HTTP Route Names](https://deepkit.io/en/documentation/http/getting-started.md#route-names). If this referenced route (query or path) contains parameters, they can be specified via the second argument:

```typescript
router.get({ path: '/user/:id', name: 'user_detail' }, (id: number) => {

});

router.post('/user', (user: HttpBody<User>) => {
    //... store user and redirect to its detail page
    return Redirect.toRoute('user_detail', { id: 23 });
});
```

Alternatively, you can redirect to a URL with `Redirect.toUrl`.

```typescript
router.post('/user', (user: HttpBody<User>) => {
    //... store user and redirect to its detail page
    return Redirect.toUrl('/user/' + 23);
});
```

By default, both use a 302 forwarding. This can be customized via the `statusCode` argument.

## Resolver

Router supports a way to resolve complex parameter types. For example, given a route such as `/user/:id`, this `id` can be resolved to a `user` object outside the route using a resolver. This further decouples HTTP abstraction and route code, further simplifying testing and modularity.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { http, RouteParameterResolverContext, RouteParameterResolver } from '@deepkit/http';

class UserResolver implements RouteParameterResolver {
    constructor(protected database: Database) {
    }

    async resolve(context: RouteParameterResolverContext) {
        if (!context.parameters.id) throw new Error('No :id given');
        return await this.database.getUser(parseInt(context.parameters.id, 10));
    }
}

@http.resolveParameter(User, UserResolver)
class MyWebsite {
    @http.GET('/user/:id')
    getUser(user: User) {
        return 'Hello ' + user.username;
    }
}

new App({
    controllers: [MyWebsite],
    providers: [UserDatabase, UserResolver],
    imports: [new FrameworkModule]
})
    .run();
```

The decorator in `@http.resolveParameter` specifies which class is to be resolved with the `UserResolver`. As soon as the specified class `User` is specified as a parameter in the function or method, the resolver is used to provide it.

If `@http.resolveParameter` is specified at the class, all methods of this class get this resolver. The decorator can also be applied per method:

```typescript
class MyWebsite {
    @http.GET('/user/:id').resolveParameter(User, UserResolver)
    getUser(user: User) {
        return 'Hello ' + user.username;
    }
}
```

Also, the functional API can be used:

```typescript

router.add(
    http.GET('/user/:id').resolveParameter(User, UserResolver),
    (user: User) => {
        return 'Hello ' + user.username;
    }
);
```

The `User` object does not necessarily have to depend on a parameter. It could just as well depend on a session or an HTTP header, and only be provided when the user is logged in. In `RouteParameterResolverContext` a lot of information about the HTTP request is available, so that many use cases can be mapped.

In principle, it is also possible to have complex parameter types provided via the Dependency Injection container from the `http` scope, since these are also available in the route function or method. However, this has the disadvantage that no asynchronous function calls can be used, since the DI container is synchronous throughout.

---

Source: https://deepkit.io/en/documentation/http/views

# HTML Views

Deepkit HTTP comes with a built-in HTML view rendering system. It's based on JSX and allows you to write your views in TypeScript. It's not a template engine with its own syntax, but a full-fledged TypeScript/JSX renderer.

It optimises the JSX code at runtime and caches the result. It's therefore very fast and has almost no overhead.


## JSX

JSX is a syntax extension to JavaScript and comes with TypeScript support out of the box. It allows you to write HTML in TypeScript. It's very similar to Vue.js or React.js.

```tsx app=app.ts
import { App } from '@deepkit/app';
import { HttpRouterRegistry } from "@deepkit/http";

export function View() {
    return <div>
        <h1>Hello World</h1>
        <p>My first JSX view</p>
    </div>;
}

const app = new App({});
const router = app.get(HttpRouterRegistry);

router.get('/', () => <View/>);

app.run();
```

```sh

---

Source: https://deepkit.io/en/documentation/http/dependency-injection

# Dependency Injection

The router functions as well as the controller classes and controller methods can define arbitrary dependencies, which are resolved by the dependency injection container. For example, it is possible to conveniently get to a database abstraction or logger.

For example, if a database has been provided as a provider, it can be injected:

```typescript
class Database {
    //...
}

const app = new App({
    providers: [
        Database,
    ],
});
```

_Functional API:_

```typescript
router.get('/user/:id', async (id: number, database: Database) => {
    return await database.query(User).filter({id}).findOne();
});
```

_Controller API:_

```typescript
class UserController {
    constructor(private database: Database) {}

    @http.GET('/user/:id')
    async userDetail(id: number) {
        return await this.database.query(User).filter({id}).findOne();
    }
}

//alternatively directly in the method
class UserController {
    @http.GET('/user/:id')
    async userDetail(id: number, database: Database) {
        return await database.query(User).filter({id}).findOne();
    }
}
```

See [Dependency Injection](https://deepkit.io/en/documentation/http/dependency-injection) to learn more.

## Scope

All HTTP controllers and functional routes are managed within the `http` dependency injection scope. HTTP controllers are instantiated accordingly for each HTTP request. This also means that both can access providers registered for the `http` scope. So additionally `HttpRequest` and `HttpResponse` from `@deepkit/http` are usable as dependencies. If deepkit framework is used, `SessionHandler` from `@deepkit/framework` is also available.

```typescript
import { HttpResponse } from '@deepkit/http';

router.get('/user/:id', (id: number, request: HttpRequest) => {
});

router.get('/', (response: HttpResponse) => {
    response.end('Hello');
});
```

It can be useful to place providers in the `http` scope, for example to instantiate services for each HTTP request. Once the HTTP request has been processed, the `http` scoped DI container is deleted, thus cleaning up all its provider instances from the garbage collector (GC).

See [Dependency Injection Scopes](https://deepkit.io/en/documentation/http/dependency-injection.md#di-scopes) to learn how to place providers in the `http` scope.

---

Source: https://deepkit.io/en/documentation/http/events

# Events

The HTTP module is based on a workflow engine that provides various event tokens that can be used to hook into the entire process of processing an HTTP request.

The workflow engine is a finite state machine that creates a new state machine instance for each HTTP request and then jumps from position to position. The first position is the `start` and the last the `response`. Additional code can be executed in each position.

![HTTP Workflow](https://deepkit.io/assets/documentation/framework/http-workflow.png)

Each event token has its own event type with additional information.

| Event-Token                   | Description                                                                                                         |
|-------------------------------|---------------------------------------------------------------------------------------------------------------------|
| httpWorkflow.onRequest        | When a new request comes in                                                                                         |
| httpWorkflow.onRoute          | When the route should be resolved from the request                                                                  |
| httpWorkflow.onRouteNotFound  | When the route is not found                                                                                         |
| httpWorkflow.onAuth           | When authentication happens                                                                                         |
| httpWorkflow.onResolveParameters | When route parameters are resolved                                                                                 |
| httpWorkflow.onAccessDenied   | When access is denied                                                                                               |
| httpWorkflow.onController     | When the controller action is called                                                                                |
| httpWorkflow.onControllerError | When the controller action threw an error                                                                           |
| httpWorkflow.onParametersFailed | When route parameters resolving failed                                                                             |
| httpWorkflow.onResponse       | When the controller action has been called. This is the place where the result is converted to a response.          |

Since all HTTP events are based on the workflow engine, its behavior can be modified by using the specified event and jumping there with the `event.next()` method.

The HTTP module uses its own event listeners on these event tokens to implement HTTP request processing. All these event listeners have a priority of 100, which means that when you listen for an event, your listener is executed first by default (since the default priority is 0). Add a priority above 100 to run after the HTTP default handler.

For example, suppose you want to catch the event when a controller is invoked. If a particular controller is to be invoked, we check if the user has access to it. If the user has access, we continue. But if not, we jump to the next workflow item `accessDenied`. There, the procedure of an access-denied is then automatically processed further.

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { HtmlResponse, http, httpAction, httpWorkflow } from '@deepkit/http';
import { eventDispatcher } from '@deepkit/event';

class MyWebsite {
    @http.GET('/')
    open() {
        return 'Welcome';
    }

    @http.GET('/admin').group('secret')
    secret() {
        return 'Welcome to the dark side';
    }
}

const app = new App({
    controllers: [MyWebsite],
    imports: [new FrameworkModule]
})

app.listen(httpWorkflow.onController, async (event) => {
    if (event.route.groups.includes('secret')) {
        //check here for authentication information like cookie session, JWT, etc.

        //this jumps to the 'accessDenied' workflow state,
        // essentially executing all onAccessDenied listeners.

        //since our listener is called before the HTTP kernel one,
        // the standard controller action will never be called.
        //this calls event.next('accessDenied', ...) under the hood
        event.accessDenied();
    }
});

/**
 * We change the default accessDenied implementation.
 */
app.listen(httpWorkflow.onAccessDenied, async () => {
    if (event.sent) return;
    if (event.hasNext()) return;
    event.send(new HtmlResponse('No access to this area.', 403));
})

app.run();
```

```sh
$ curl http://localhost:8080/
Welcome
$ curl http://localhost:8080/admin
No access to this area
```

---

Source: https://deepkit.io/en/documentation/http/middleware

# Middleware

HTTP middlewares allow you to hook into the request/response cycle as an alternative to HTTP events. Its API allows you to use all middlewares from the Express/Connect framework.

A middleware can either be a class (which is instantiated by the dependency injection container) or a simple function.

```typescript
import { HttpMiddleware, httpMiddleware, HttpRequest, HttpResponse } from '@deepkit/http';

class MyMiddleware implements HttpMiddleware {
    async execute(request: HttpRequest, response: HttpResponse, next: (err?: any) => void) {
        response.setHeader('middleware', '1');
        next();
    }
}


function myMiddlewareFunction(request: HttpRequest, response: HttpResponse, next: (err?: any) => void) {
    response.setHeader('middleware', '1');
    next();
}

new App({
    providers: [MyMiddleware],
    middlewares: [
        httpMiddleware.for(MyMiddleware),
        httpMiddleware.for(myMiddlewareFunction),
    ],
    imports: [new FrameworkModule]
}).run();
```

## Global

By using httpMiddleware.for(MyMiddleware) a middleware is registered for all routes, globally.

```typescript
import { httpMiddleware } from '@deepkit/http';

new App({
    providers: [MyMiddleware],
    middlewares: [
        httpMiddleware.for(MyMiddleware)
    ],
    imports: [new FrameworkModule]
}).run();
```

## Per Controller

You can limit middlewares to one or multiple controllers in two ways. Either by using the `@http.controller` or `httpMiddleware.for(T).forControllers()`. `excludeControllers` allow you to exclude controllers.

```typescript
@http.middleware(MyMiddleware)
class MyFirstController {

}
new App({
    providers: [MyMiddleware],
    controllers: [MainController, UsersCommand],
    middlewares: [
        httpMiddleware.for(MyMiddleware).forControllers(MyFirstController, MySecondController)
    ],
    imports: [new FrameworkModule]
}).run();
```

## Per Route Name

`forRouteNames` along with its counterpart `excludeRouteNames` allow you to filter the execution of a middleware per route names.

```typescript
class MyFirstController {
    @http.GET('/hello').name('firstRoute')
    myAction() {
    }

    @http.GET('/second').name('secondRoute')
    myAction2() {
    }
}
new App({
    controllers: [MainController, UsersCommand],
    providers: [MyMiddleware],
    middlewares: [
        httpMiddleware.for(MyMiddleware).forRouteNames('firstRoute', 'secondRoute')
    ],
    imports: [new FrameworkModule]
}).run();
```


## Per Action/Route

To execute a middleware only for a certain route, you can either use `@http.GET().middleware()` or
`httpMiddleware.for(T).forRoute()` where forRoute has multiple options to filter routes.

```typescript
class MyFirstController {
    @http.GET('/hello').middleware(MyMiddleware)
    myAction() {
    }
}
new App({
    controllers: [MainController, UsersCommand],
    providers: [MyMiddleware],
    middlewares: [
        httpMiddleware.for(MyMiddleware).forRoutes({
            path: 'api/*'
        })
    ],
    imports: [new FrameworkModule]
}).run();
```

`forRoutes()` allows as first argument several way to filter for routes.

```typescript
{
    path?: string;
    pathRegExp?: RegExp;
    httpMethod?: 'GET' | 'HEAD' | 'POST' | 'PATCH' | 'PUT' | 'DELETE' | 'OPTIONS' | 'TRACE';
    category?: string;
    excludeCategory?: string;
    group?: string;
    excludeGroup?: string;
}
```

## Path Pattern

`path` supports wildcard *.

```typescript
httpMiddleware.for(MyMiddleware).forRoutes({
    path: 'api/*'
})
```

## RegExp

```typescript
httpMiddleware.for(MyMiddleware).forRoutes({
    pathRegExp: /'api/.*'/
})
```

## HTTP Method

Filter all routes by a HTTP method.

```typescript
httpMiddleware.for(MyMiddleware).forRoutes({
    httpMethod: 'GET'
})
```

## Category

`category` along with its counterpart `excludeCategory` allow you to filter per route category.

```typescript
@http.category('myCategory')
class MyFirstController {

}

class MySecondController {
    @http.GET().category('myCategory')
    myAction() {
    }
}
httpMiddleware.for(MyMiddleware).forRoutes({
    category: 'myCategory'
})
```

## Group

`group` along with its counterpart `excludeGroup` allow you to filter per route group.

```typescript
@http.group('myGroup')
class MyFirstController {

}

class MySecondController {
    @http.GET().group('myGroup')
    myAction() {
    }
}
httpMiddleware.for(MyMiddleware).forRoutes({
    group: 'myGroup'
})
```

## Per Modules

You can limit the execution of a module for a whole module.

```typescript
httpMiddleware.for(MyMiddleware).forModule(ApiModule)
```


## Per Self Modules

To execute a middleware for all controllers/routes of a module where the middleware was registered use `forSelfModules()`.

```typescript
const ApiModule = new AppModule({}, {
    controllers: [MainController, UsersCommand],
    providers: [MyMiddleware],
    middlewares: [
        //for all controllers registered of the same module
        httpMiddleware.for(MyMiddleware).forSelfModules(),
    ],
});
```

## Calling next()

A middleware either calls `next()` to continue with the next middleware and finally the controller, or ends the response itself, for example with `response.end()`. Then the controller is not executed and `next()` must not be called. `onResponse` listeners and the HTTP logger still run.

```typescript
function authentication(request: HttpRequest, response: HttpResponse, next: (err?: any) => void) {
    if (!request.headers['authorization']) {
        response.statusCode = 401;
        response.end();
        return;
    }
    next();
}
```

Calling `next(error)` or throwing an error (also in an async middleware) fails the request:

- An `HttpError` like `HttpUnauthorizedError` is answered with its status code and its message as JSON, like in a controller.
- Any other error is logged and answered with 500 "Internal error".

If the middleware already ended the response, the response stays as it is.

## Timeout

By default, a middleware has no timeout. With `timeout(milliseconds)`, a middleware that neither calls `next()` nor ends the response within that time fails the request with `HttpGatewayTimeoutError` (504), and a warning is logged. A later call of `next()` is ignored.

```typescript
const ApiModule = new AppModule({}, {
    controllers: [MainController, UsersCommand],
    providers: [MyMiddleware],
    middlewares: [
        //for all controllers registered of the same module
        httpMiddleware.for(MyMiddleware).timeout(15_000),
    ],
});
```

## Multiple Rules

To combine multiple filters, you can chain method calls.

```typescript
const ApiModule = new AppModule({}, {
    controllers: [MyController],
    providers: [MyMiddleware],
    middlewares: [
        httpMiddleware.for(MyMiddleware).forControllers(MyController).excludeRouteNames('secondRoute')
    ],
});
```

## Express Middleware

Almost all express middlewares are supported. Those who access certain request methods of express are not yet supported.

```typescript
import * as compression from 'compression';

const ApiModule = new AppModule({}, {
    middlewares: [
        httpMiddleware.for(compress()).forControllers(MyController)
    ],
});
```

---

Source: https://deepkit.io/en/documentation/http/security

# Security

This section is still under construction.

---

Source: https://deepkit.io/en/documentation/rpc

# RPC

RPC, which stands for Remote Procedure Call, allows functions on a remote server to be called as if they were local functions. Unlike HTTP client-server communication, which uses HTTP methods and a URL for mapping, RPC uses the function name for mapping. The data to be sent is passed as normal function arguments, and the result of the function call on the server is sent back to the client.

The advantage of RPC is that the client-server abstraction is lightweight because it does not work with headers, URLs, query strings, or similar. The disadvantage is that functions on a server via RPC cannot be easily called by a browser and often require a specific client.


One key feature of RPC is that the data between the client and server is automatically serialized and deserialized. Therefore, typesafe RPC clients are usually possible. Some RPC frameworks force users to provide types (parameter types and return types) in a specific format. This can be in the form of a DSL such as Protocol Buffers for gRPC and GraphQL or a JavaScript schema builder. Additional data validation can also be provided by the RPC framework but is not supported by all.

Deepkit RPC extracts types from the TypeScript code itself, so it is not necessary to use a code generator or define them manually. Deepkit supports automatic serialization and deserialization of parameters and results. Once additional restrictions are defined in Validation, they are automatically validated. This makes communication via RPC extremely typesafe and efficient. The support for streaming via `rxjs` in Deepkit RPC makes this RPC framework a suitable tool for real-time communication.

To illustrate the concept behind RPC, consider the following code:

```typescript
//server.ts
class Controller {
    hello(title: string): string {
        return 'Hello ' + title
    }
}
```

A method like hello is implemented just like a normal function within a class on the server and can be called by a remote client.

```typescript
//client.ts
const client = new RpcClient('localhost');
const controller = client.controller<Controller>();

const result = await controller.hello('World'); // => 'Hello World';
```

Because RPC is fundamentally based on asynchronous communication, communication is usually over HTTP but can also be over TCP or WebSockets. This means that all function calls in TypeScript are converted to a `Promise` themselves. The result can be received asynchronously with a corresponding `await`.

## Isomorphic TypeScript

When a project uses TypeScript on both the client (usually frontend) and server (backend), it is called Isomorphic TypeScript. A typesafe RPC framework based on TypeScript's types is particularly beneficial for such a project because types can be shared between the client and server.

To take advantage of this, types that are used on both sides should be outsourced to their own file or package. Importing on the respective side then puts them back together.

```typescript
//shared.ts
export class User {
    id: number;
    username: string;
}

//server.ts
import { User } from './shared';

@rpc.controller('/user')
class UserController  {
    async getUser(id: number): Promise<User> {
        return await datbase.query(User).filter({id}).findOne();
    }
}

//client.ts
import { UserControllerApi } from './shared';
import type { UserController } from './server.ts'
const controller = client.controller<UserController>('/user');
const user = await controller.getUser(2); // => User
```

Backward compatibility can be implemented in the same way as with a normal local API: either new parameters are marked as optional or a new method is added.

---

Source: https://deepkit.io/en/documentation/rpc/getting-started

# Getting Started

To use Deepkit RPC, it is necessary to have `@deepkit/type` correctly installed because it is based on Runtime Types. See [Runtime Type Installation](https://deepkit.io/en/documentation/runtime-types.md).

Once this is successfully done, `@deepkit/rpc` or the Deepkit Framework, which already uses the library under the hood, can be installed.

```sh
npm install @deepkit/rpc
```

Note that controller classes in `@deepkit/rpc` are based on TypeScript decorators, and this feature must be enabled with experimentalDecorators.

The `@deepkit/rpc` package must be installed on the server and client if they have their own package.json.

To communicate over TCP with the server, the `@deepkit/rpc-tcp` package must be installed on the client and server.

```sh
npm install @deepkit/rpc-tcp
```

For WebSocket communication, the package is also required on the server. The client in the browser, on the other hand, uses WebSocket from the official standard.

If the client is also to be used in an environment where WebSocket is not available (for example, NodeJS), the package ws is required in the client.

```sh
npm install ws
```

## Usage

Below is a fully functional example based on WebSockets and the low-level API of @deepkit/rpc. When using the Deepkit Framework, controllers are provided via app modules, and an RpcKernel is not instantiated manually.

_File: server.ts_

```typescript
import { rpc, RpcKernel } from '@deepkit/rpc';
import { RpcWebSocketServer } from '@deepkit/rpc-tcp';

@rpc.controller('/main')
export class Controller {
    @rpc.action()
    hello(title: string): string {
        return 'Hello ' + title;
    }
}

const kernel = new RpcKernel();
kernel.registerController(Controller);
const server = new RpcWebSocketServer(kernel, 'localhost:8081');
server.start({
    host: '127.0.0.1',
    port: 8081,
});
console.log('Server started at ws://127.0.0.1:8081');

```

_File: client.ts_

```typescript
import { RpcWebSocketClient } from '@deepkit/rpc';
import type { Controller } from './server';

async function main() {
    const client = new RpcWebSocketClient('ws://127.0.0.1:8081');
    const controller = client.controller<Controller>('/main');

    const result = await controller.hello('World');
    console.log('result', result);

    client.disconnect();
}

main().catch(console.error);

```

## Server Controller

The term "Procedure" in Remote Procedure Call is also commonly referred to as an "Action". An Action is a method defined in a class and marked with the `@rpc.action` decorator. The class itself is marked as a Controller with the `@rpc.controller` decorator and given a unique name. This name is then referenced in the client to address the correct controller. Multiple controllers can be defined and registered as needed.


```typescript
import { rpc } from '@deepkit/rpc';

@rpc.controller('/main');
class Controller {
    @rpc.action()
    hello(title: string): string {
        return 'Hello ' + title;
    }

    @rpc.action()
    test(): boolean {
        return true;
    }
}
```

Only methods marked as `@rpc.action()` can be called by a client.

Types must be explicitly specified and cannot be inferred. This is important because the serializer needs to know exactly what the types look like in order to convert them into binary data (BSON) or JSON which is then sent over the wire.

## Client Controller

The normal flow in RPC is that the client can execute functions on the server. However, in Deepkit RPC, it is also possible for the server to execute functions on the client. To allow this, the client can also register a controller.

TODO

## Dependency Injection

When the Deepkit framework is used, the class is instantiated by the Dependency Injection container and thus automatically has access to all other providers in the application.

See also [Dependency Injection](https://deepkit.io/en/documentation/rpc/dependency-injection.md#).

## Streaming RxJS

TODO

## Nominal Types

When the client receives data from a function call, it has first been serialized on the server and then deserialized on the client. If the function's return type includes classes, these classes will be reconstructed on the client side, but they will lose their nominal identity and associated methods. To address this issue, register the classes as nominal types with unique IDs/names. This approach should be applied to all classes used within an RPC-API.

To register a class, use the decorator `@entity.name('id')`.

```typescript
import { entity } from '@deepkit/type';

@entity.name('user')
class User {
    id!: number;
    firstName!: string;
    lastName!: string;
    get fullName() {
        return this.firstName + ' ' + this.lastName;
    }
}
```

Once this class is used as the result of a function, its identity will be preserved.

```typescript
const controller = client.controller<Controller>('/main');

const user = await controller.getUser(2);
user instanceof User; //true when @entity.name is used, and false if not
```

---

Source: https://deepkit.io/en/documentation/rpc/dependency-injection

# Dependency Injection

Controller classes are managed by the Dependency Injection Container from `@deepkit/injector`. When using the Deepkit Framework, these controllers automatically have access to the providers of the modules that provide the controller.

In the Deepkit Framework, controllers are instantiated in the Dependency Injection Scope `rpc`, allowing all controllers to automatically access various providers from this scope. These additional providers are `HttpRequest` (optional), `RpcInjectorContext`, `SessionState`, `RpcKernelConnection`, and `ConnectionWriter`.

```typescript
import { RpcKernel, rpc } from '@deepkit/rpc';
import { App } from '@deepkit/app';
import { Database, User } from './database';

@rpc.controller('/main')
class Controller {
    constructor(private database: Database) {
    }

    @rpc.action()
    async getUser(id: number): Promise<User> {
        return await this.database.query(User).filter({ id }).findOne();
    }
}

new App({
    providers: [{ provide: Database, useValue: new Database }]
    controllers: [Controller],
}).run();
```

However, when an `RpcKernel` is manually instantiated, a DI Container can also be passed. The RPC Controller will then be instantiated through this DI Container. This is useful if you want to use `@deepkit/rpc` in a non-Deepkit Framework environment, like Express.js.

```typescript
import { RpcKernel, rpc } from '@deepkit/rpc';
import { InjectorContext } from '@deepkit/injector';
import { Database, User } from './database';

@rpc.controller('/main')
class Controller {
    constructor(private database: Database) {
    }

    @rpc.action()
    async getUser(id: number): Promise<User> {
        return await this.database.query(User).filter({ id }).findOne();
    }
}

const injector = InjectorContext.forProviders([
    Controller,
    { provide: Database, useValue: new Database },
]);
const kernel = new RpcKernel(injector);
kernel.registerController(Controller);
```

See [Dependency Injection](https://deepkit.io/en/documentation/dependency-injection.md) to learn more.

---

Source: https://deepkit.io/en/documentation/rpc/security

# Security

By default, all RPC functions can be called from any client, and the peer-to-peer communication feature is enabled. To precisely control which client is allowed to do what, you can override the `RpcKernelSecurity` class.

```typescript
import { RpcKernelSecurity, Session, RpcControllerAccess } from '@deepkit/type';

//contains default implementations
class MyKernelSecurity extends RpcKernelSecurity {
    async hasControllerAccess(session: Session, controllerAccess: RpcControllerAccess): Promise<boolean> {
        return true;
    }

    async isAllowedToRegisterAsPeer(session: Session, peerId: string): Promise<boolean> {
        return true;
    }

    async isAllowedToSendToPeer(session: Session, peerId: string): Promise<boolean> {
        return true;
    }

    async authenticate(token: any): Promise<Session> {
        throw new Error('Authentication not implemented');
    }

    transformError(err: Error) {
        return err;
    }
}
```

To use this, pass the provider to the `RpcKernel`:

```typescript
const kernel = new RpcKernel([{provide: RpcKernelSecurity, useClass: MyKernelSecurity, scope: 'rpc'}]);
```

Or, in the case of a Deepkit app, override the `RpcKernelSecurity` class with a provider in the app:

```typescript
import { App } from '@deepkit/type';
import { RpcKernelSecurity } from '@deepkit/rpc';
import { FrameworkModule } from '@deepkit/framework';

new App({
    controllers: [MyRpcController],
    providers: [
        {provide: RpcKernelSecurity, useClass: MyRpcKernelSecurity, scope: 'rpc'}
    ],
    imports: [new FrameworkModule]
}).run();
```

## Authentication / Session

By default, the `Session` object is an anonymous session, meaning the client has not authenticated. When the client wants to authenticate, the `authenticate` method is called. The token received by the `authenticate` method comes from the client and can have any value.

Once the client sets a token, the authentication is executed when the first RPC function is called or when `client.connect()` is manually invoked.


```typescript
const client = new RpcWebSocketClient('localhost:8081');
client.token.set('123456789');

const controller = client.controller<Controller>('/main');
```

In this case, `RpcKernelSecurity.authenticate` receives the token `123456789` and can return a different session accordingly. The returned session is then passed to all other methods like `hasControllerAccess`.

```typescript
import { Session, RpcKernelSecurity } from '@deepkit/rpc';

class UserSession extends Session {
}

class MyKernelSecurity extends RpcKernelSecurity {
    async hasControllerAccess(session: Session, controllerAccess: RpcControllerAccess): Promise<boolean> {
        if (controllerAccess.controllerClassType instanceof MySecureController) {
            //MySecureController requires UserSession
            return session instanceof UserSession;
        }
        return true;
    }

    async authenticate(token: any): Promise<Session> {
        if (token === '123456789') {
            //username can be an ID or a username
            return new UserSession('username', token);
        }
        throw new Error('Authentication failed');
    }
}
```

## Controller Access

The `hasControllerAccess` method determines whether a client is allowed to execute a specific RPC function. This method is called for every RPC function invocation. If it returns `false`, access is denied, and an error is thrown on the client.

The `RpcControllerAccess` contains valuable information about the RPC function:

```typescript
interface RpcControllerAccess {
    controllerName: string;
    controllerClassType: ClassType;
    actionName: string;
    actionGroups: string[];
    actionData: { [name: string]: any };
}
```

Groups and additional data can be changed via the decorator `@rpc.action()`:

```typescript
class Controller {
    @rpc.action().group('secret').data('role', 'admin')
    saveUser(user: User): void {
    }
}

class MyKernelSecurity extends RpcKernelSecurity {
    async hasControllerAccess(session: Session, controllerAccess: RpcControllerAccess): Promise<boolean> {
        if (controllerAccess.actionGroups.includes('secret')) {
            if (session instanceof UserSession) {
                //todo: check
                return session.username === 'admin';
            }
            return false;
        }
        return true;
    }
}
```

---

Source: https://deepkit.io/en/documentation/rpc/errors

# Errors

Thrown errors are automatically forwarded to the client with all its information like the error message and also the stacktrace.

If nominal instances for the error object is import (because you use instanceof), it is required to use `@entity.name('@error:unique-name')` so that the given error class is registered in the runtime and reused.

```typescript
@entity.name('@error:myError')
class MyError extends Error {}

//server
@rpc.controller('/main')
class Controller {
    @rpc.action()
    saveUser(user: User): void {
        throw new MyError('Can not save user');
    }
}

//client
//[MyError] makes sure the class MyError is known in runtime
const controller = client.controller<Controller>('/main', [MyError]);

try {
    await controller.getUser(2);
} catch (e) {
    if (e instanceof MyError) {
        //ops, could not save user
    } else {
        //all other errors
    }
}
```

## Transform Error

Since thrown errors are automatically forwarded to the client with all its information like the error message and also the stacktrace, this could unwantedly publish sensitive information. To change this, in the method `transformError` the thrown error can be modified.

```typescript
class MyKernelSecurity extends RpcKernelSecurity {
    constructor(private logger: Logger) {
        super();
    }

    transformError(error: Error) {
        //wrap in new error
        this.logger.error('Error in RPC', error);
        return new Error('Something went wrong: ' + error.message);
    }
}
```

Note that once the error is converted to a generic `error`, the complete stack trace and the identity of the error are lost. Accordingly, no `instanceof` checks can be used on the error in the client.

If Deepkit RPC is used between two microservices, and thus the client and server are under complete control of the developer, then transforming the error is rarely necessary. If, on the other hand, the client is running in a browser with an unknown, then care should be taken in `transformError` as to what information is to be disclosed. If in doubt, each error should be transformed with a generic `Error` to ensure that no internal details are leaked. Logging the error would then be a good idea at this point.

---

Source: https://deepkit.io/en/documentation/rpc/transport

# Transport Protocol

Deepkit RPC supports several transport protocols. WebSockets is the protocol that has the best compatibility (since browsers support it) while supporting all features like streaming. TCP is usually faster and is great for communication between servers (microservices) or non-browser clients. But WebSockets work well for server to server communication as well.

## HTTP

Deepkit's RPC HTTP protocol is a variant that is particularly easy to debug in the browser, as each function call is an HTTP request, but has its limitations such as no support for RxJS streaming.

TODO: Not implemented yet.

## WebSockets

@deepkit/rpc-tcp `RpcWebSocketServer` and Browser WebSocket or Node `ws` package.

## TCP

@deepkit/rpc-tcp `RpcNetTcpServer` and `RpcNetTcpClientAdapter`

---

Source: https://deepkit.io/en/documentation/orm

# Deepkit ORM

Deepkit ORM is a high-performance TypeScript ORM (Object-Relational Mapper). It provides a simple and intuitive API for interacting with databases, allowing you to focus on building your application rather than worrying about low-level database operations. The ORM is built on top of Deepkit's Runtime Type System, which provides a typesafe environment for working with databases.

## Why an ORM?

Object-Relational Mapping (ORM) in Deepkit provides several benefits for developers.

1. Simplified Database Operations: With an ORM, developers can abstract away the manual creation and execution of SQL queries. Instead, they can use a more intuitive object-oriented approach to interact with the database. This simplifies common database operations such as querying, inserting, updating, and deleting records.

2. Cross-Database Compatibility: An ORM allows developers to write database-agnostic code by providing a consistent API to interact with different database systems. This means that you can easily switch between different database engines, like MySQL, PostgreSQL, or SQLite, without having to make significant changes to your codebase.

3. Type Safety and Compile-Time Checks: By utilizing runtime type information, Deepkit's ORM provides a typesafe environment for working with databases. With the ORM, you can define database schemas as TypeScript classes or interfaces, allowing you to catch potential errors at compile-time rather than during runtime. Additionally, the ORM handles automatic type conversions and validation, ensuring that your data is always consistent and correctly persisted in the database.

Overall, using an ORM in Deepkit simplifies database operations, improves cross-database compatibility, and provides type safety and compile-time checks, making it an essential component for building robust and maintainable applications.

---

Source: https://deepkit.io/en/documentation/orm/getting-started

# Getting Started

Deepkit provides a Database ORM that allows databases to be accessed in a modern way.
Entities are simply defined using TypeScript types:

```typescript
import { entity, PrimaryKey, AutoIncrement, 
    Unique, MinLength, MaxLength } from '@deepkit/type';

type Username = string & Unique & MinLength<2> & MaxLength<16>;

// class entity
@entity.name('user')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;
    firstName?: string;
    lastName?: string;

    constructor(
        public username: Username,
        public email: string & Unique,
    ) {}
}

// or as interface
interface User {
    id: number & PrimaryKey & AutoIncrement;
    created: Date;
    firstName?: string;
    lastName?: string;
    username: Username;
    email: string & Unique;
}
```

Any TypeScript types and validation decorators from Deepkit can be used to fully define the entity.
The entity type system is designed in such a way that these types or classes can also be used in other areas such as HTTP routes, RPC actions or frontend. This prevents, for example, that one has defined a user several times distributed in the entire application.

## Installation

Since Deepkit ORM is based on Runtime Types, it is necessary to have `@deepkit/type` already installed correctly.
See [Runtime Type Installation](https://deepkit.io/en/documentation/runtime-types/getting-started.md).

If this is done successfully, `@deepkit/orm` itself and a database adapter can be installed.

If classes are to be used as entities, `experimentalDecorators` must be enabled in tsconfig.json:

```json
{
  "compilerOptions": {
    "experimentalDecorators": true
  }
}
```

Once the library is installed, a database adapter can be installed and the API of it can be used directly.

### SQLite

```sh
npm install @deepkit/orm @deepkit/sqlite
```

```typescript
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';

const database = new Database(new SQLiteDatabaseAdapter('./example.sqlite'), [User]);
const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User]);
```

### MySQL

```sh
npm install @deepkit/orm @deepkit/mysql
```

```typescript
import { MySQLDatabaseAdapter } from '@deepkit/mysql';

const database = new Database(new MySQLDatabaseAdapter({
    host: 'localhost',
    port: 3306
}), [User]);
```

### Postgres

```sh
npm install @deepkit/orm @deepkit/postgres
```

```typescript
import { PostgresDatabaseAdapter } from '@deepkit/postgres';

const database = new Database(new PostgresDatabaseAdapter({
    host: 'localhost',
    port: 3306
}), [User]);
```

### MongoDB

```sh
npm install @deepkit/orm @deepkit/bson @deepkit/mongo
```

```typescript
import { MongoDatabaseAdapter } from '@deepkit/mongo';

const database = new Database(new MongoDatabaseAdapter('mongodb://localhost/mydatabase'), [User]);
```

## Usage

Primarily the `Database` object is used. Once instantiated, it can be used throughout the application to query or manipulate data. The connection to the database is initialized lazy.

The `Database` object is passed an adapter, which comes from the database adapters libraries.

```typescript
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { entity, PrimaryKey, AutoIncrement } from '@deepkit/type';
import { Database } from '@deepkit/orm';

async function main() {
    @entity.name('user')
    class User {
        public id: number & PrimaryKey & AutoIncrement = 0;
        created: Date = new Date;

        constructor(public name: string) {
        }
    }

    const database = new Database(new SQLiteDatabaseAdapter('./example.sqlite'), [User]);
    await database.migrate(); //create tables

    await database.persist(new User('Peter'));

    const allUsers = await database.query(User).find();
    console.log('all users', allUsers);
}

main();
```

### Database

### Connection

#### Read Replica

## Repository

## Index

## Case Sensitivity

## Character Sets

## Collations

## Batching

## Caching

## Multitenancy

## Naming Strategy

## Locking

### Optimistic Locking

### Pessimistic Locking

## Custom Types

## Logging

## Migration

## Seeding

## Raw Database Access

### SQL

### MongoDB

## Plugins

---

Source: https://deepkit.io/en/documentation/orm/entity

# Entity

An entity is either a class or an object literal (interface) and always has a primary key.
The entity is decorated with all necessary information using type annotations from `@deepkit/type`. For example, a primary key is defined as well as various fields and their validation constraints. These fields reflect the database structure, usually a table or a collection.

Through special type annotations like `Mapped<'name'>` a field name can also be mapped to another name in the database.

## Class

```typescript
import { entity, PrimaryKey, AutoIncrement, Unique, MinLength, MaxLength } from '@deepkit/type';

@entity.name('user')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;
    firstName?: string;
    lastName?: string;

    constructor(
        public username: string & Unique & MinLength<2> & MaxLength<16>,
        public email: string & Unique,
    ) {}
}

const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User]);
await database.migrate();

await database.persist(new User('Peter'));

const allUsers = await database.query(User).find();
console.log('all users', allUsers);
```

## Interface

```typescript
import { PrimaryKey, AutoIncrement, Unique, MinLength, MaxLength } from '@deepkit/type';

interface User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;
    firstName?: string;
    lastName?: string;
    username: string & Unique & MinLength<2> & MaxLength<16>;
}

const database = new Database(new SQLiteDatabaseAdapter(':memory:'));
database.register<User>({name: 'user'});

await database.migrate();

const user: User = {id: 0, created: new Date, username: 'Peter'};
await database.persist(user);

const allUsers = await database.query<User>().find();
console.log('all users', allUsers);
```

## Primitives

Primitive data types like String, Number (bigint), and Boolean are mapped to common database types. Only the TypeScript type is used.

```typescript

interface User {
    logins: number;
    username: string;
    pro: boolean;
}
```

## Primary Key

Each entity needs exactly one primary key. Multiple primary keys are not supported.

The base type of a primary key can be arbitrary. Often a number or UUID is used.
For MongoDB the MongoId or ObjectID is often used.

For numbers `AutoIncrement` can be used.

```typescript
import { PrimaryKey } from '@deepkit/type';

interface User {
    id: number & PrimaryKey;
}
```

## Auto Increment

Fields that should be automatically incremented during insertion are annotated with the `AutoIncrement` decorator. All adapters support auto-increment values. The MongoDB adapter uses an additional collection to keep track of the counter.

An auto-increment field is an automatic counter and can only be applied to a primary key. The database automatically ensures that an ID is used only once.

```typescript
import { PrimaryKey, AutoIncrement } from '@deepkit/type';

interface User {
    id: number & PrimaryKey & AutoIncrement;
}
```

## UUID

Fields that should be of type UUID (v4) are annotated with the decorator UUID. The runtime type is `string` and mostly binary in the database itself. Use the `uuid()` function to create a new UUID v4.

```typescript
import { uuid, UUID, PrimaryKey } from '@deepkit/type';

class User {
    id: UUID & PrimaryKey = uuid();
}
```

## MongoDB ObjectID

Fields that should be of type ObjectID in MongoDB are annotated with the decorator `MongoId`. The runtime type is `string` and in the database itself `ObjectId` (binary).

MongoID fields automatically get a new value when inserted. It is not mandatory to use the field name `_id`. It can have any name.

```typescript
import { PrimaryKey, MongoId } from '@deepkit/type';

class User {
    id: MongoId & PrimaryKey = '';
}
```

## Optional / Nullable

Optional fields are declared as TypeScript type with `title?: string` or `title: string | null`. You should use only one variant of this, usually the optional `?` syntax, which works with `undefined`.
Both variants result in the database type being `NULLABLE` for all SQL adapters. So the only difference between these decorators is that they represent different values at runtime.

In the following example, the changed field is optional and can therefore be undefined at runtime, although it is always represented as NULL in the database.

```typescript
import { PrimaryKey } from '@deepkit/type';

class User {
    id: number & PrimaryKey = 0;
    modified?: Date;
}
```

This example shows how the nullable type works. NULL is used both in the database and in the javascript runtime. This is more verbose than `modified?: Date` and is not commonly used.

```typescript
import { PrimaryKey } from '@deepkit/type';

class User {
    id: number & PrimaryKey = 0;
    modified: Date | null = null;
}
```

## Database Type Mapping

|===
|Runtime type|SQLite|MySQL|Postgres|Mongo

|string|text|longtext|text|string
|number|float|double|double precision|int/number
|boolean|integer(1)|boolean|boolean|boolean
|date|text|datetime|timestamp|datetime
|array|text|json|jsonb|array
|map|text|json|jsonb|object
|map|text|json|jsonb|object
|union|text|json|jsonb|T
|uuid|blob|binary(16)|uuid|binary
|ArrayBuffer/Uint8Array/...|blob|longblob|bytea|binary
|===

With `DatabaseField` it is possible to map a field to any database type. The type must be a valid SQL statement that is passed unchanged to the migration system.

```typescript
import { DatabaseField } from '@deepkit/type';

interface User {
    title: string & DatabaseField<{type: 'VARCHAR(244)'}>;
}
```

To map a field for a specific database, either `SQLite`, `MySQL`, or `Postgres` can be used.

### SQLite

```typescript
import { SQLite } from '@deepkit/type';

interface User {
    title: string & SQLite<{type: 'text'}>;
}
```

### MySQL

```typescript
import { MySQL } from '@deepkit/type';

interface User {
    title: string & MySQL<{type: 'text'}>;
}
```

### Postgres

```typescript
import { Postgres } from '@deepkit/type';

interface User {
    title: string & Postgres<{type: 'text'}>;
}
```

## Embedded Types

## Default Values

## Default Expressions

## Complex Types

## Exclude

## Database Specific Column Types

---

Source: https://deepkit.io/en/documentation/orm/session

# Session / Unit Of Work

A session is something like a unit of work. It keeps track of everything you do and automatically records the changes whenever `commit()` is called. It is the preferred way to execute changes in the database because it bundles statements in a way that makes it very fast. A session is very lightweight and can easily be created in a request-response lifecycle, for example.

```typescript
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { entity, PrimaryKey, AutoIncrement } from '@deepkit/type';
import { Database } from '@deepkit/orm';

async function main() {

    @entity.name('user')
    class User {
        id: number & PrimaryKey & AutoIncrement = 0;
        created: Date = new Date;

        constructor(public name: string) {
        }
    }

    const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User]);
    await database.migrate();

    const session = database.createSession();
    session.add(new User('User1'), new User('User2'), new User('User3'));

    await session.commit();

    const users = await session.query(User).find();
    console.log(users);
}

main();
```

Add new instance to the session with `session.add(T)` or remove existing instances with `session.remove(T)`. Once you are done with the Session object, simply dereference it everywhere so that the garbage collector can remove it.

Changes are automatically detected for entity instances fetched via the Session object.

```typescript
const users = await session.query(User).find();
for (const user of users) {
    user.name += ' changed';
}

await session.commit();//saves all users
```

## Identity Map

Sessions provide an identity map that ensures there is only ever one javascript object per database entry. For example, if you run `session.query(User).find()` twice within the same session, you get two different arrays, but with the same entity instances in them.

If you add a new entity with `session.add(entity1)` and retrieve it again, you get exactly the same entity instance `entity1`.

Important: Once you start using sessions, you should use their `session.query` method instead of `database.query`. Only session queries have the identity mapping feature enabled.

## Change Detection

## Request/Response

---

Source: https://deepkit.io/en/documentation/orm/query

# Query

A query is an object that describes how to retrieve or modify data from the database. It has several methods to describe the query and termination methods that execute them. The database adapter can extend the query API in many ways to support database specific features.

You can create a query using `Database.query(T)` or `Session.query(T)`. We recommend Sessions as it improves performance.

```typescript
@entity.name('user')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;
    birthdate?: Date;
    visits: number = 0;

    constructor(public username: string) {
    }
}

const database = new Database(...);

//[ { username: 'User1' }, { username: 'User2' }, { username: 'User2' } ]
const users = await database.query(User).select('username').find();
```

## Filter

A filter can be applied to limit the result set.

```typescript
//simple filters
const users = await database.query(User).filter({name: 'User1'}).find();

//multiple filters, all AND
const users = await database.query(User).filter({name: 'User1', id: 2}).find();

//range filter: $gt, $lt, $gte, $lte (greater than, lower than, ...)
//equivalent to WHERE created < NOW()
const users = await database.query(User).filter({created: {$lt: new Date}}).find();
//equivalent to WHERE id > 500
const users = await database.query(User).filter({id: {$gt: 500}}).find();
//equivalent to WHERE id >= 500
const users = await database.query(User).filter({id: {$gte: 500}}).find();

//set filter: $in, $nin (in, not in)
//equivalent to WHERE id IN (1, 2, 3)
const users = await database.query(User).filter({id: {$in: [1, 2, 3]}}).find();

//regex filter
const users = await database.query(User).filter({username: {$regex: /User[0-9]+/}}).find();

//grouping: $and, $nor, $or
//equivalent to WHERE (username = 'User1') OR (username = 'User2')
const users = await database.query(User).filter({
    $or: [{username: 'User1'}, {username: 'User2'}]
}).find();


//nested grouping
//equivalent to WHERE username = 'User1' OR (username = 'User2' and id > 0)
const users = await database.query(User).filter({
    $or: [{username: 'User1'}, {username: 'User2', id: {$gt: 0}}]
}).find();


//nested grouping
//equivalent to WHERE username = 'User1' AND (created < NOW() OR id > 0)
const users = await database.query(User).filter({
    $and: [{username: 'User1'}, {$or: [{created: {$lt: new Date}, id: {$gt: 0}}]}]
}).find();
```

### Equal

### Greater / Smaller

### RegExp

### Grouping AND/OR

### In

## Select

To narrow down the fields to be received from the database, `select('field1')` can be used.

```typescript
const user = await database.query(User).select('username').findOne();
const user = await database.query(User).select('id', 'username').findOne();
```

It is important to note that as soon as the fields are narrowed down using `select`, the results are no longer instances of the entity, but only object literals.

```
const user = await database.query(User).select('username').findOne();
user instanceof User; //false
```

## Order

With `orderBy(field, order)` the order of the entries can be changed.
Several times `orderBy` can be executed to refine the order more and more.

```typescript
const users = await session.query(User).orderBy('created', 'desc').find();
const users = await session.query(User).orderBy('created', 'asc').find();
```

## Pagination

The `itemsPerPage()` and `page()` methods can be used to paginate the results. Page starts at 1.

```typescript
const users = await session.query(User).itemsPerPage(50).page(1).find();
```

With the alternative methods `limit` and `skip` you can paginate manually.

```typescript
const users = await session.query(User).limit(5).skip(10).find();
```

[#database-join]
## Join

By default, references from the entity are neither included in queries nor loaded. To include a join in the query without loading the reference, use `join()` (left join) or `innerJoin()`. To include a join in the query and load the reference, use `joinWith()` or `innerJoinWith()`.

All the following examples assume these model schemas:

```typescript
@entity.name('group')
class Group {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    constructor(public username: string) {
    }
}

@entity.name('user')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    group?: Group & Reference;

    constructor(public username: string) {
    }
}
```

```typescript
//select only users with a group assigned (INNER JOIN)
const users = await session.query(User).innerJoin('group').find();
for (const user of users) {
    user.group; //error, since reference was not loaded
}
```

```typescript
//select only users with a group assigned (INNER JOIN) and load the relation
const users = await session.query(User).innerJoinWith('group').find();
for (const user of users) {
    user.group.name; //works
}
```

To modify join queries, use the same methods, but with the `use` prefix: `useJoin`, `useInnerJoin`, `useJoinWith` or `useInnerJoinWith`. To end the join query modification, use `end()` to get back the parent query.

```typescript
//select only users with a group with name 'admins' assigned (INNER JOIN)
const users = await session.query(User)
    .useInnerJoinWith('group')
        .filter({name: 'admins'})
        .end()  // returns to the parent query
    .find();

for (const user of users) {
    user.group.name; //always admin
}
```

## Aggregation

Aggregation methods allow you to count records and aggregate fields.

The following examples assume this model scheme:

```typescript
@entity.name('file')
class File {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    downloads: number = 0;

    category: string = 'none';

    constructor(public path: string & Index) {
    }
}
```

`groupBy` allows to group the result by the specified field.

```typescript
await database.persist(
    cast<File>({path: 'file1', category: 'images'}),
    cast<File>({path: 'file2', category: 'images'}),
    cast<File>({path: 'file3', category: 'pdfs'})
);

//[ { category: 'images' }, { category: 'pdfs' } ]
await session.query(File).groupBy('category').find();
```

There are several aggregation methods: `withSum`, `withAverage`, `withCount`, `withMin`, `withMax`, `withGroupConcat`. Each requires a field name as the first argument and an optional second argument to change the alias.

```typescript
// first let's update some of the records:
await database.query(File).filter({path: 'images/file1'}).patchOne({$inc: {downloads: 15}});
await database.query(File).filter({path: 'images/file2'}).patchOne({$inc: {downloads: 5}});

//[{ category: 'images', downloads: 20 },{ category: 'pdfs', downloads: 0 }]
await session.query(File).groupBy('category').withSum('downloads').find();

//[{ category: 'images', downloads: 10 },{ category: 'pdfs', downloads: 0 }]
await session.query(File).groupBy('category').withAverage('downloads').find();

//[ { category: 'images', amount: 2 }, { category: 'pdfs', amount: 1 } ]
await session.query(File).groupBy('category').withCount('id', 'amount').find();
```

## Returning

With `returning` additional fields can be requested in case of changes via `patch` and `delete`.

Caution: Not all database adapters return fields atomically. Use transactions to ensure data consistency.

```typescript
await database.query(User).patchMany({visits: 0});

//{ modified: 1, returning: { visits: [ 5 ] }, primaryKeys: [ 1 ] }
const result = await database.query(User)
    .filter({username: 'User1'})
    .returning('username', 'visits')
    .patchOne({$inc: {visits: 5}});
```

## Find

Returns an array of entries matching the specified filter.

```typescript
const users: User[] = await database.query(User).filter({username: 'Peter'}).find();
```

## FindOne

Returns an item that matches the specified filter.
If no item is found, an `ItemNotFound` error is thrown.

```typescript
const users: User = await database.query(User).filter({username: 'Peter'}).findOne();
```

## FindOneOrUndefined

Returns an entry that matches the specified filter.
If no entry is found, undefined is returned.

```typescript
const query = database.query(User).filter({username: 'Peter'});
const users: User|undefined = await query.findOneOrUndefined();
```

## FindField

Returns a list of a field that match the specified filter.

```typescript
const usernames: string[] = await database.query(User).findField('username');
```

## FindOneField

Returns a list of a field that match the specified filter.
If no entry is found, an `ItemNotFound` error is thrown.

```typescript
const username: string = await database.query(User).filter({id: 3}).findOneField('username');
```

## Patch

Patch is a change query that patches the records described in the query. The methods
`patchOne` and `patchMany` finish the query and execute the patch.

`patchMany` changes all records in the database that match the specified filter. If no filter is set, the whole table will be changed. Use `patchOne` to change only one entry at a time.

```typescript
await database.query(User).filter({username: 'Peter'}).patch({username: 'Peter2'});

await database.query(User).filter({username: 'User1'}).patchOne({birthdate: new Date});
await database.query(User).filter({username: 'User1'}).patchOne({$inc: {visits: 1}});

await database.query(User).patchMany({visits: 0});
```

## Delete

`deleteMany` deletes all entries in the database that match the specified filter.
If no filter is set, the whole table will be deleted. Use `deleteOne` to delete only one entry at a time.

```typescript
const result = await database.query(User)
    .filter({visits: 0})
    .deleteMany();

const result = await database.query(User).filter({id: 4}).deleteOne();
```

## Has

Returns whether at least one entry exists in the database.

```typescript
const userExists: boolean = await database.query(User).filter({username: 'Peter'}).has();
```

## Count

Returns the number of entries.

```typescript
const userCount: number = await database.query(User).count();
```

## Lift

Lifting a query means adding new functionality to it. This is usually used either by plugins or complex architectures to split larger query classes into several convenient, reusable classes.

```typescript
import { FilterQuery, Query } from '@deepkit/orm';

class UserQuery<T extends {birthdate?: Date}> extends Query<T>  {
    hasBirthday() {
        const start = new Date();
        start.setHours(0,0,0,0);
        const end = new Date();
        end.setHours(23,59,59,999);

        return this.filter({$and: [{birthdate: {$gte: start}}, {birthdate: {$lte: end}}]} as FilterQuery<T>);
    }
}

await session.query(User).lift(UserQuery).hasBirthday().find();
```

---

Source: https://deepkit.io/en/documentation/orm/transactions

# Transactions

A transaction is a sequential group of statements, queries, or operations such as select, insert, update, or delete that are executed as a single unit of work that can be committed or rolled back.

Deepkit supports transactions for all officially supported databases. By default, no transactions are used for any query or database session. To enable transactions, there are two main methods: sessions and callback.

## Session Transactions

You can start and assign a new transaction for each session you create. This is the preferred way of interacting with the database, as you can easily pass on the Session object and all queries instantiated by this session will be automatically assigned to its transaction.

A typical pattern is to wrap all operations in a try-catch block and execute `commit()` on the very last line (which is only executed if all previous commands succeeded) and `rollback()` in the catch block to roll back all changes as soon as an error occurs.

Although there is an alternative API (see below), all transactions work only with database session objects. To commit open changes from the unit-of-work in a database session to the database, `commit()` is normally called. In a transactional session, `commit()` not only commits all pending changes to the database, but also completes ("commits") the transaction, thus closing the transaction. Alternatively, you can call `session.flush()` to commit all pending changes without `commit` and thus without closing the transaction. To commit a transaction without flushing the unit-of-work, use `session.commitTransaction()`.

```typescript
const session = database.createSession();

//this assigns a new transaction, and starts it with the very next database operation.
session.useTransaction();

try {
    //this query is executed in the transaction
    const users = await session.query(User).find();

    await moreDatabaseOperations(session);

    await session.commit();
} catch (error) {
    await session.rollback();
}
```

Once `commit()` or `rollback()` is executed in a session, the transaction is released. You must then call `useTransaction()` again if you want to continue in a new transaction.

Please note that once the first database operation is executed in a transactional session, the assigned database connection becomes fixed and exclusive to the current session object (sticky). Thus, all subsequent operations will be performed on the same connection (and thus, in most databases, on the same database server). Only when either the transactional session is terminated (commit or rollback), the database connection is released again. It is therefore recommended to keep a transaction only as short as necessary.

If a session is already connected to a transaction, a call to `session.useTransaction()` always returns the same object. Use `session.isTransaction()` to check if a transaction is associated with the session.

Nested transactions are not supported.

## Transaction Callback

An alternative to transactional sessions is `database.transaction(callback)`.

```typescript
await database.transaction(async (session) => {
    //this query is executed in the transaction
    const users = await session.query(User).find();

    await moreDatabaseOperations(session);
});
```

The `database.transaction(callback)` method performs an asynchronous callback within a new transactional session. If the callback succeeds (that is, no error is thrown), the session is automatically committed (and thus its transaction committed and all changes flushed). If the callback fails, the session automatically executes `rollback()` and the error is propagated.

## Isolations

Many databases support different types of transactions. To change the transaction behavior, you can call different methods for the returned transaction object from `useTransaction()`. The interface of this transaction object depends on the database adapter used. For example, the transaction object returned from a MySQL database has different options than the one returned from a MongoDB database. Use code completion or view the database adapter's interface to get a list of possible options.

```typescript
const database = new Database(new MySQLDatabaseAdapter());

const session = database.createSession();
session.useTransaction().readUncommitted();

try {
    //...operations
    await session.commit();
} catch (error) {
    await session.rollback();
}

//or
await database.transaction(async (session) => {
    //this works as long as no database operation has been exuected.
    session.useTransaction().readUncommitted();

    //...operations
});
```

While transactions for MySQL, PostgreSQL, and SQLite work by default, you must first set up MongoDB as a "replica set".

To convert a standard MongoDB instance to a replica set, please refer to the official documentation link:
[Convert a Standalone to a Replica Set](https://docs.mongodb.com/manual/tutorial/convert-standalone-to-replica-set).

---

Source: https://deepkit.io/en/documentation/orm/inheritance

# Inheritance

There are several ways to implement inheritance in Deepkit ORM.

## Class Inheritance

One way is the use of class inheritance, which uses simple classes with `extends`.

```typescript
import { PrimaryKey, AutoIncrement } from '@deepkit/type';

class BaseModel {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;
    updated: Date = new Date;
}

class User extends BaseModel {
    name: string = '';
}

class Customer extends BaseModel {
    name: string = '';
    address: string = '';
}

new Database(
    new SQLiteDatabaseAdapter('./example.sqlite'),
    [User, Customer]
);
```

Since `BaseModel` will not be used as entity, it isn't registered in the database. Only `User` and `Customer` will be registered as entities and mapped to a table with all the properties of `BaseModel` included.

The SQL tables would look like this:

```sql
CREATE TABLE user (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    created TEXT NOT NULL,
    updated TEXT NOT NULL,
    name TEXT NOT NULL
);

CREATE TABLE customer (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    created TEXT NOT NULL,
    updated TEXT NOT NULL,
    name TEXT NOT NULL,
    address TEXT NOT NULL
);
```

## Single Table Inheritance

Single Table Inheritance is a way to store multiple entities in one table.  Instead of having separate tables for each model, a single table is used, and an additional column (often named type or similar) is utilized to determine the type of each record. This is useful if you have a lot of entities that share the same properties.

```typescript
import { PrimaryKey, AutoIncrement, entity } from '@deepkit/type';

@entity.collection('persons')
abstract class Person {
    id: number & PrimaryKey & AutoIncrement = 0;
    firstName?: string;
    lastName?: string;
    abstract type: string;
}

@entity.singleTableInheritance()
class Employee extends Person {
    email?: string;

    type: 'employee' = 'employee';
}

@entity.singleTableInheritance()
class Freelancer extends Person {
    @t budget: number = 10_000;

    type: 'freelancer' = 'freelancer';
}

new Database(
    new SQLiteDatabaseAdapter('./example.sqlite'), 
    [Employee, Freelancer]
);
```

The `Person` class is not an entity and thus not registered in the database. The `Employee` and `Freelancer` classes are entities and will be mapped to a single table with the name `persons`. The `type` column will be used to determine the type of each record.

A SQL table would look like this:

```sql
CREATE TABLE persons (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    firstName TEXT,
    lastName TEXT,
    type TEXT NOT NULL,
    email TEXT,
    budget INTEGER
);
``` 

As you can see budget is made optional (even though in `Freelance` class it is required). This is to support inserting `Employee` (which doesn't have a budget value)
into the same table. This is a limitation of the single table inheritance.

---

Source: https://deepkit.io/en/documentation/orm/relations

# Relations

Relationships allow you to connect two entities in a certain way. This is usually done in databases using the concept of foreign keys. Deepkit ORM supports relations for all official database adapters.

A relation is annotated with the `Reference` decorator. Usually a relation also has a reverse relation, which is annotated with the `BackReference` type, but is only needed if the reverse relation is to be used in a database query. Back references are only virtual.

## One To Many

The entity that stores a reference is usually referred to as the `owning side` or the one that `owns` the reference. The following code shows two entities with a one-to-many relationship between `User` and `Post`. This means that one `User` can have multiple `Post`. The `post` entity has the `post->user` relationship. In the database itself there is now a field `Post. "author"` that contains the primary key of `User`.

```typescript
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { entity, PrimaryKey, AutoIncrement, 
    Reference } from '@deepkit/type';
import { Database } from '@deepkit/orm';

@entity.collection('users')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    constructor(public username: string) {
    }
}

@entity.collection('posts')
class Post {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    constructor(
        public author: User & Reference,
        public title: string
    ) {
    }
}

const database = new Database(
    new SQLiteDatabaseAdapter(':memory:'), 
    [User, Post]
);
await database.migrate();

const user1 = new User('User1');
const post1 = new Post(user1, 'My first blog post');
const post2 = new Post(user1, 'My second blog post');

await database.persist(user1, post1, post2);
```

References are not selected in queries by default. See [Database Joins](https://deepkit.io/en/documentation/orm/query.md#join) for details.

## Many To One

A reference usually has a reverse reference called many-to-one. It is only a virtual reference, since it is not reflected in the database itself. A back reference is annotated `BackReference` and is mainly used for reflection and query joins. If you add a `BackReference` from `User` to `Post`, you can join `Post` directly from `User` queries.

```typescript
@entity.name('user').collection('users')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    posts?: Post[] & BackReference;

    constructor(public username: string) {
    }
}
```

```typescript
//[ { username: 'User1', posts: [ [Post], [Post] ] } ]
const users = await database.query(User)
    .select('username', 'posts')
    .joinWith('posts')
    .find();
```

## Many To Many

A many-to-many relationship allows you to associate many records with many others. For example, it can be used for users in groups. A user can be in none, one or many groups. Consequently, a group can contain 0, one or many users.

Many-to-many relationships are usually implemented using a pivot entity. The pivot entity contains the actual own references to two other entities, and these two entities have back references to the pivot entity.

```typescript
@entity.name('user')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    groups?: Group[] & BackReference<{via: typeof UserGroup}>;

    constructor(public username: string) {
    }
}

@entity.name('group')
class Group {
    id: number & PrimaryKey & AutoIncrement = 0;

    users?: User[] & BackReference<{via: typeof UserGroup}>;

    constructor(public name: string) {
    }
}

//the pivot entity
@entity.name('userGroup')
class UserGroup {
    id: number & PrimaryKey & AutoIncrement = 0;

    constructor(
        public user: User & Reference,
        public group: Group & Reference,
    ) {
    }
}
```

With these entities, you can now create users and groups and connect them to the pivot entity. By using a back reference in User, we can retrieve the groups directly with a User query.

```typescript
const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User, Group, UserGroup]);
await database.migrate();

const user1 = new User('User1');
const user2 = new User('User2');
const group1 = new Group('Group1');

await database.persist(user1, user2, group1, new UserGroup(user1, group1), new UserGroup(user2, group1));

//[
//   { id: 1, username: 'User1', groups: [ [Group] ] },
//   { id: 2, username: 'User2', groups: [ [Group] ] }
// ]
const users = await database.query(User)
    .select('username', 'groups')
    .joinWith('groups')
    .find();
```

To unlink a user from a group, the UserGroup record is deleted:

```typescript
const users = await database.query(UserGroup)
    .filter({user: user1, group: group1})
    .deleteOne();
```

## One To One

## Constraints

On Delete/Update: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

---

Source: https://deepkit.io/en/documentation/orm/events

# Events

Events are a way to hook into Deepkit ORM and allow you to write powerful plugins. There are two
categories of events: Query events and Unit-of-Work events. Plugin authors typically use both to
support both ways of manipulating data.

Events are registered via `Database.listen` un an event token. Short-lived event listeners can also
be registered on sessions.

```typescript
import { Query, Database } from '@deepkit/orm';

const database = new Database(...);
database.listen(Query.onFetch, async (event) => {
});

const session = database.createSession();

//will only be executed for this particular session
session.eventDispatcher.listen(Query.onFetch, async (event) => {
});
```

## Query Events

Query events are triggered when a query is executed via `Database.query()` or `Session.query()`.

Each event has its own additional properties such as the type of entity, the query itself and the
database session. You can override the query by setting a new query to `Event.query`.

```typescript
import { Query, Database } from '@deepkit/orm';

const database = new Database(...);

const unsubscribe = database.listen(Query.onFetch, async event => {
    //overwrite the query of the user, so something else is executed.
    event.query = event.query.filterField('fieldName', 123);
});

//to delete the hook call unsubscribe
unsubscribe();
```

"Query" has several event tokens:

| Event-Token        | Description                                                 |
|--------------------|-------------------------------------------------------------|
| Query.onFetch      | When objects where fetched via find()/findOne()/etc         |
| Query.onDeletePre  | Before objects are deleted via deleteMany/deleteOne()       |
| Query.onDeletePost | After objects are deleted via deleteMany/deleteOne()        |
| Query.onPatchPre   | Before objects are patched/updated via patchMany/patchOne() |
| Query.onPatchPost  | After objects are patched/updated via patchMany/patchOne()  |

## Unit Of Work Events

Unit-of-work events are triggered when a new session submits changes.

| Event-Token                  | Description                                                                                                       |
|------------------------------|-------------------------------------------------------------------------------------------------------------------|
| DatabaseSession.onUpdatePre  | Triggered just before the `DatabaseSession` object initiates an update operation on the database records.         |
| DatabaseSession.onUpdatePost | Triggered immediately after the `DatabaseSession` object has successfully completed the update operation.         |
| DatabaseSession.onInsertPre  | Triggered just before the `DatabaseSession` object starts the insertion of new records into the database.         |
| DatabaseSession.onInsertPost | Triggered immediately after the `DatabaseSession` object has successfully inserted the new records.               |
| DatabaseSession.onDeletePre  | Triggered just before the `DatabaseSession` object begins a delete operation to remove records from the database. |
| DatabaseSession.onDeletePost | Triggered immediately after the `DatabaseSession` object has completed the delete operation.                      |
| DatabaseSession.onCommitPre  | Triggered just before the `DatabaseSession` object commits any changes made during the session to the database.   |

---

Source: https://deepkit.io/en/documentation/orm/migrations

# Migrations

Migrations are a way to make database schema changes in a structured and organized manner. They are stored as TypeScript files in a directory and can be executed using the command-line tool.

Deepkit ORM migrations are enabled by default when Deepkit Framework is used. 

## Commands

- `migration:create` - Generates a new migration file based on a database diff
- `migration:pending` - Shows pending migration files
- `migration:up` - Executes pending migration files.
- `migration:down` - Executes down migration, reverting old migration files

These commands are available either in application when you import the `FrameworkModule` or via the `deepkit-sql` command-line tool from `@deepkit/sql`.

The [migration integration of FrameworkModule](https://deepkit.io/en/documentation/framework/database.md#migration) automatically reads your Databases (you have to define them as provider), while with `deepkit-sql` you have to specify the TypeScript file that exports the database. THe latter is useful if you use Deepkit ORM standalone without Deepkit Framework.

## Creating a migration

```typescript
//database.ts
import { Database } from '@deepkit/orm';
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { User } from './models';

export class SQLiteDatabase extends Database {
    name = 'default';
    constructor() {
        super(new SQLiteDatabaseAdapter('/tmp/myapp.sqlite'), [User]);
    }
}

export const database = new SQLiteDatabase();
```

```sh
./node_modules/.bin/deepkit-sql migration:create --path database.ts --migrationDir src/migrations
```

`--path` takes files that export `Database` instances (it can be given multiple times). TypeScript files are loaded with `ts-node`, which has to be installed, so that the entities get their runtime types.

A new migration file is created in `src/migrations`. 

The newly created migration file contains now the up and down methods based on the difference between the entities defined in your TypeScript app and the configured database. 
You can now modify the up method to your needs. The down method is automatically generated based on the up method.
You commit this file to your repository so that other developers can also execute it.

## Pending Migrations

```sh
./node_modules/.bin/deepkit-sql migration:pending --path database.ts --migrationDir src/migrations
```

This shows all pending migrations. If you have a new migration file that is not executed yet, it will be listed here.

## Executing Migrations

```sh
./node_modules/.bin/deepkit-sql migration:up --path database.ts --migrationDir src/migrations
```

This executes the next pending migration. 

## Reverting Migrations

```sh
./node_modules/.bin/deepkit-sql migration:down --path database.ts --migrationDir src/migrations
```

This reverts the last executed migration.

## Fake migrations

Let's say you wanted to execute a migration (up or down), but it failed. You fixed the issue manually, but now you can't execute the migration again, because it's already executed. You can use the `--fake` option to fake the migration, so that it's marked as executed in the database without actually executing it. This way you can execute the next pending migration.

```sh
./node_modules/.bin/deepkit-sql migration:up --path database.ts --migrationDir src/migrations --fake
```

---

Source: https://deepkit.io/en/documentation/orm/orm-browser

# ORM Browser

Deepkit ORM Browser is a web-based tool to explore your database schema and data. It is built on top of the Deepkit Framework and can be used with any database supported by the Deepkit ORM.

![ORM Browser](https://deepkit.io/assets/screenshots-orm-browser/content-editing.png)

## Installation

Deepkit ORM Browser is part of the Deepkit Framework and enabled when debug mode is enabled.

```typescript
import { App } from '@deepkit/app';
import { Database } from '@deepkit/orm';

class MyController {
    @http.GET('/')
    index() {
        return 'Hello World';
    }
}

class MainDatabase extends Database {
    constructor() {
        super(new DatabaseAdapterSQLite());
    }
}

new App({
    controllers: [MyController],
    providers: [MainDatabase],
    imports: [new FrameworkModule({debug: true})],
}).run();
```

Alternatively, you can install Deepkit ORM Browser as a standalone package.

```bash
npm install @deepkit/orm-browser
```

```typescript
// database.ts
import { Database } from '@deepkit/orm';

class MainDatabase extends Database {
    constructor() {
        super(new DatabaseAdapterSQLite());
    }
}

export const database = new MainDatabase();
```

Next, Deepkit ORM Browser server can be started.

```sh
./node_modules/.bin/deepkit-orm-browser database.ts
```

Deepkit ORM Browser is now available at http://localhost:9090.

---

Source: https://deepkit.io/en/documentation/orm/raw-access

# Raw Access

It's often necessary to access the database directly, for example to run a SQL query that is not supported by the ORM.
This can be done using the `raw` method on the `Database` class.

```typescript
import { PrimaryKey, AutoIncrement, @entity } from '@deepkit/type';
import { Database } from '@deepkit/orm';
import { sql } from '@deepkit/sql';
import { SqliteDatabaseAdapter } from '@deepkit/sqlite';

@entity.collection('users')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;
    constructor(public username: string) {}
}

const database = new Database(new SQLiteDatabaseAdapter(':memory:'), [User]);

const query = 'Pet%';
const rows = await database.raw<User>(sql`SELECT * FROM users WHERE username LIKE ${query}`).find();

const result = await database.raw<{ count: number }>(sql`SELECT count(*) as count FROM users WHERE username LIKE ${query}`).findOne();
console.log('Found', result.count, 'users');
```

The SQL query is built using the `sql` template string tag. This is a special template string tag that allows to pass values as parameters. These parameters are then automatically parsed and converted to a safe prepared statement. This is important to avoid SQL injection attacks.

To pass a dynamic identifier like a column name, `identifier` can be used:

```typescript
import { identifier, sql } from '@deepkit/sql';

let column = 'username';
const rows = await database.raw<User>(sql`SELECT * FROM users WHERE ${identifier(column)} LIKE ${query}`).find();
```

For SQL adapters, the `raw` method returns an `RawQuery` with `findOne` and `find` methods to retrieve the results. To execute a SQL without returning rows like UPDATE/DELETE/etc, `execute` can be used:

```typescript
let username = 'Peter';
await database.raw(sql`UPDATE users SET username = ${username} WHERE id = 1`).execute();
```

`RawQuery` also supports getting the final SQL string and parameters, correctly formatted for the database adapter:

```typescript
const query = database.raw(sql`SELECT * FROM users WHERE username LIKE ${query}`);
console.log(query.sql);
console.log(query.params);
```

This way the SQL can be used to execute it in a different database client, for example.

## Types

Note that you can pass any type to `raw` and the result from the database will be automatically converted to that type. This is especially useful for SQL adapters, where you can pass a class and the result will be automatically converted to that class.

This has limitations though. SQL Joins are not supported this way. If you want to use joins, you have to use the ORM's query builder.

## Mongo

MongoDB adapter works a bit different since it's not based on SQL queries but on Mongo commands.

A command could be an aggregation pipeline, a find query, or a write command.

```typescript
import { MongoDatabaseAdapter } from '@deepkit/mongo';

const database = new Database(MongoDatabaseAdapter('mongodb://localhost:27017/mydatabase'));

// first argument is entry point collection, second is the command's return type
const items = await database.raw<ChatMessage, { count: number }>([
    { $match: { roomId: 'room1' } },
    { $group: { _id: '$userId', count: { $sum: 1 } } },
]).find();
```

---

Source: https://deepkit.io/en/documentation/orm/seeding

# Seeding

Database seeding is the initial seeding of a database with data. It is a form of initial database population, intended for use during development, testing, or production database initialization.

---

Source: https://deepkit.io/en/documentation/orm/composite-primary-key

# Composite Primary Key

Composite Primary-Key means, an entity has several primary keys, which are automatically combined to a "composite primary key". This way of modeling the database has advantages and disadvantages. We believe that composite primary keys have huge practical disadvantages that do not justify their advantages, so they should be considered bad practice and therefore avoided. Deepkit ORM does not support composite primary keys. In this chapter we explain why and show (better) alternatives.

## Disadvantages

Joins are not trivial. Although they are highly optimized in RDBMS, they represent a constant complexity in applications that can easily get out of hand and lead to performance problems. Performance not only in terms of query execution time, but also in terms of development time.

## Joins

Each individual join becomes more complicated as more fields are involved. While many databases have implemented optimizations to make joins with multiple fields not slower per se, it requires the developer to constantly think through these joins in detail, since forgetting keys, for example, can lead to subtle errors (since the join will work even without specifying all keys) and the developer therefore needs to know the full composite primary key structure.

## Indizes

Indexes with multiple fields (which are composite primary keys) suffer from the problem of field ordering in queries. While database systems can optimize certain queries, complex structures make it difficult to write efficient operations that correctly use all defined indexes. For an index with multiple fields (such as a composite primary key), it is usually necessary to define the fields in the correct order for the database to actually use the index. If the order is not specified correctly (for example, in a WHERE clause), this can easily result in the database not using the index at all and instead performing a full table scan. Knowing which database query optimizes in which way is advanced knowledge that new developers don't usually have, but is necessary once you start working with composite primary keys so that you get the most out of your database and don't waste resources.

## Migrationen

Once you decide that a particular entity needs an additional field to uniquely identify it (and thus become the Composite Primary Key), this will result in the adjustment of all entities in your database that have relationships to that entity.

For example, suppose you have an entity `user` with composite primary key and decide to use a foreign key to this `user` in different tables, e.g. in a pivot table `audit_log`, `groups` and `posts`. Once you change the primary key of `user`, all these tables need to be adjusted in a migration as well.

Not only does this make migration files much more complex, but it can also cause major downtime when running migration files, since schema changes usually require either a full database lock or at least a table lock. The more tables affected by a large change like an index change, the longer the migration will take. And the larger a table is, the longer the migration takes.
Consider the `audit_log` table. Such tables usually have many records (millions or so), and you have to touch them during a schema change only because you decided to use a composite primary key and add an extra field to the primary key of `user`. Depending on the size of all these tables, this either makes migration changes unnecessarily more expensive or, in some cases, so expensive that changing the primary key of `User` is no longer financially justifiable. This usually leads to workarounds (e.g. adding a unique index to the user table) that result in technical debt and sooner or later end up on the legacy list.

For large projects, this can lead to huge downtime (from minutes to hours) and sometimes even the introduction of an entirely new migration abstraction system that essentially copies tables, inserts records into ghost tables, and moves tables back and forth after migration. This added complexity is in turn imposed on any entity that has a relationship to another entity with a composite primary key, and becomes greater the larger your database structure becomes. The problem gets worse with no way to solve it (except by removing the composite primary key entirely).

## Findability

If you are a database administrator or Data Engineer/Scientist, you usually work directly on the database and explore the data when you need it. With composite primary keys, any user writing SQL directly must know the correct primary key of all tables involved (and the column order to get correct index optimizations). This added overhead not only complicates data exploration, report generation, etc., but can also lead to errors in older SQL if a composite primary key is suddenly changed. The old SQL is probably still valid and running fine, but suddenly returns incorrect results because the new field in the composite primary key is missing from the join. It is much easier here to have only one primary key. This makes it easier to find data and ensures that old SQL queries will still work correctly if you decide to change the way a user object is uniquely identified, for example.

## Revision

Once a composite primary key is used in an entity, refactoring the key can result in significant additional refactoring. Because an entity with a composite primary key typically does not have a single unique field, all filters and links must contain all values of the composite key. This usually means that the code relies on knowing the composite primary key, so all fields must be retrieved (e.g., for URLs like user:key1:key2). Once this key is changed, all places where this knowledge is explicitly used, such as URLs, custom SQL queries, and other places, must be rewritten.

While ORMs typically create joins automatically without manually specifying the values, they cannot automatically cover refactoring for all other use cases such as URL structures or custom SQL queries, and especially not for places where the ORM is not used at all, such as in reporting systems and all external systems.

## ORM complexity

With the support of composite primary keys, the complexity of the code of a powerful ORM like Deepkit ORM increases tremendously. Not only will the code and maintenance become more complex and therefore more expensive, but there will be more edge cases from users that need to be fixed and maintained. The complexity of the query layer, change detection, migration system, internal relationship tracking, etc. increases significantly. The overall cost associated with building and supporting an ORM with composite primary keys is too high, all things considered, and cannot be justified, which is why Deepkit does not support it.

## Advantages

Apart from this, composite primary keys also have advantages, albeit very superficial ones. By using as few indexes as possible for each table, writing (inserting/updating) data becomes more efficient, since fewer indexes need to be maintained. It also makes the structure of the model a bit cleaner (since it usually has one less column). However, the difference between a sequentially ordered, automatically incrementing primary key and a non-incrementing primary key is completely negligible these days, since disk space is cheap and the operation is usually just an "append-only" operation, which is very fast.

There may certainly be a few edge cases (and for a few very specific database systems) where it is initially better to work with composite primary keys. But even in these systems, it might make more sense overall (considering all the costs) not to use them and to switch to another strategy.

## Alternative

An alternative to composite primary keys is to use a single automatically incrementing numeric primary key, usually called "id", and move the composite primary key to a unique index with multiple fields. Depending on the primary key used (depending on the expected number of rows), the "id" uses either 4 or 8 bytes per record.

By using this strategy, you are no longer forced to think about the problems described above and find a solution, which enormously reduces the cost of ever-growing projects.

The strategy specifically means that each entity has an "id" field, usually at the very beginning, and this field is then used to identify unique rows by default and in joins.

```typescript
class User {
    id: number & PrimaryKey & AutoIncrement = 0;

    constructor(public username: string) {}
}
```

As an alternative to a composite primary key, you would use a unique multi-field index instead.

```typescript
@entity.index(['tenancyId', 'username'], {unique: true})
class User {
    id: number & PrimaryKey & AutoIncrement = 0;

    constructor(
        public tenancyId: number,
        public username: string,
    ) {}
}
```

Deepkit ORM automatically supports incremental primary keys, including for MongoDB. This is the preferred method for identifying records in your database. However, for MongoDB you can use the ObjectId (`_id: MongoId & PrimaryKey = ''`) as a simple primary key. An alternative to the numeric, auto-incrementing primary key is a UUID, which works just as well (but has slightly different performance characteristics, since indexing is more expensive).

## Summary

Composite primary keys essentially mean that once they are in place, all future changes and practical use come at a much higher cost. While it looks like a clean architecture at the beginning (because you have one less column), it leads to significant practical costs once the project is actually developed, and the costs continue to increase as the project gets larger.

Looking at the asymmetries between benefits and drawbacks, it is clear that composite primary keys cannot be justified in most cases. The costs are much greater than the benefits. Not only for you as a user, but also for us as the author and maintainer of the ORM code. For this reason, Deepkit ORM does not support composite primary keys.

---

Source: https://deepkit.io/en/documentation/orm/plugin-soft-delete

# Soft-Delete

The Soft-Delete plugin allows to keep database records hidden without actually deleting them. When a record is deleted, it is only marked as deleted and not actually deleted. All queries automatically filter for this deleted property, so it feels to the user as if it is actually deleted.

To use the plugin, you must instantiate the SoftDelete class and enable it for each entity.

```typescript
import { entity, PrimaryKey, AutoIncrement } from '@deepkit/type';
import { SoftDelete } from '@deepkit/orm';

@entity.name('user')
class User {
    id: number & PrimaryKey & AutoIncrement = 0;
    created: Date = new Date;

    // this field is used as indicator whether the record is soft deleted.
    // if it is set, the record is soft deleted.
    deletedAt?: Date;

    // this field is optional and can be used to track who/what deleted the record.
    deletedBy?: string;

    constructor(
        public name: string
    ) {
    }
}

const softDelete = new SoftDelete(database);
softDelete.enable(User);

//or disable again
softDelete.disable(User);
```

## Delete

To soft-delete records, use the usual methods: `deleteOne` or `deleteMany` in a query, or use the session to delete them. The soft-delete plugin will do the rest automatically in the background.

## Restore

Deleted records can be restored using a lifted query via `SoftDeleteQuery`. It has `restoreOne` and `restoreMany`.

```typescript
import { SoftDeleteQuery } from '@deepkit/orm';

await database.query(User).lift(SoftDeleteQuery).filter({ id: 1 }).restoreOne();
await database.query(User).lift(SoftDeleteQuery).filter({ id: 1 }).restoreMany();
```

The session also supports element recovery.

```typescript
import { SoftDeleteSession } from '@deepkit/orm';

const session = database.createSession();
const user1 = session.query(User).findOne();

session.from(SoftDeleteSession).restore(user1);
await session.commit();
```

## Hard Delete

To hard delete records, use a lifted query via SoftDeleteQuery. This essentially restores the normal behavior where no soft-delete plugin is used.

```typescript
import { SoftDeleteQuery } from '@deepkit/orm';

// really delete the record from the database
await database.query(User).lift(SoftDeleteQuery).hardDeleteOne();
await database.query(User).lift(SoftDeleteQuery).hardDeleteMany();

//those are equal to the one above
await database.query(User).lift(SoftDeleteQuery).withSoftDeleted().deleteOne();
await database.query(User).lift(SoftDeleteQuery).withSoftDeleted().deleteMany();
```

## Query deleted.

With a "lifted" query via `SoftDeleteQuery` you can also include deleted records.

```typescript
import { SoftDeleteQuery } from '@deepkit/orm';

// find all, soft deleted and not deleted
await database.query(User).lift(SoftDeleteQuery).withSoftDeleted().find();

// find only soft deleted
await database.query(s).lift(SoftDeleteQuery).isSoftDeleted().count()
```

## Deleted by

`deletedBy` can be set via query and sessions.

```typescript
import { SoftDeleteSession } from '@deepkit/orm';

const session = database.createSession();
const user1 = session.query(User).findOne();

session.from(SoftDeleteSession).setDeletedBy('Peter');
session.remove(user1);

await session.commit();
import { SoftDeleteQuery } from '@deepkit/orm';

database.query(User).lift(SoftDeleteQuery)
.deletedBy('Peter')
.deleteMany();
```

---

Source: https://deepkit.io/en/documentation/package/angular-ssr

# API `@deepkit/angular-ssr`

```shell
npm install @deepkit/angular-ssr
```


- Make sure to put your main application inside `app.ts` and configure it in your `angular.json`:

In `src/server/app.ts`:

```typescript
import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { AngularModule, RequestHandler } from '@deepkit/angular-ssr';

const app = new App({
  controllers: [
    // your controllers
  ],
  providers: [
    // your providers
  ],
  imports: [
    new FrameworkModule({}),
    new AngularModule({
      moduleUrl: import.meta.url,
    })
  ]
});

const main = isMainModule(import.meta.url);

if (main) {
  void app.run(); //allows to call all CLI commands, including server:start
}

export const reqHandler = main
  //when in main, we don't want to create a new request handler
  ? () => undefined
  : app.get(RequestHandler).create();
```

```json
{
  "builder": "@angular-devkit/build-angular:application",
  "options": {
    "outputPath": "dist/app",
    "index": "src/index.html",
    "server": "src/main.server.ts",
    "outputMode": "server",
    "ssr": {
      "entry": "src/server/app.ts"
    },
    "browser": "src/main.ts"
  }
}
```

Make sure to have `src/server/app.ts` also in your tsconfig.

## Configure Angular App

In `app/app.config.ts` (client side):

```typescript
@Injectable()
export class APIInterceptor implements HttpInterceptor {
  constructor(@Inject('baseUrl') @Optional() private baseUrl: string) {
    // In client build, `baseUrl` is empty and should be inferred from the current location.
    // If this is not correct, you can simply define the `baseUrl` in the `providers` array of the `appConfig` object.
    this.baseUrl = baseUrl || (typeof location !== 'undefined' ? location.origin : '');
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const apiReq = req.clone({ url: `${this.baseUrl}/${req.url}` });
    return next.handle(apiReq);
  }
}

export const appConfig: ApplicationConfig = {
  providers: [
    {
      provide: HTTP_INTERCEPTORS,
      useClass: APIInterceptor,
      multi: true,
    },
    // your other providers
  ],
};
```

In `app/app.server.config.ts` (server side):

```typescript
import { appConfig } from './app.config';

const serverConfig: ApplicationConfig = {
  providers: [
    provideServerRendering(),
    provideServerRouting([
      {
        path: '**',
        renderMode: RenderMode.Server,
      },
    ]),
    {
      provide: HTTP_TRANSFER_CACHE_ORIGIN_MAP,
      deps: [REQUEST_CONTEXT],
      useFactory(context: any) {
        return { [context?.baseUrl]: context?.publicBaseUrl || '' };
      },
    },
    {
      provide: 'baseUrl',
      deps: [REQUEST_CONTEXT],
      useFactory: (context: any) => {
        return context?.baseUrl || '';
      },
    }
  ],
};

export const config = mergeApplicationConfig(appConfig, serverConfig);
```


API reference of @deepkit/angular-ssr: https://deepkit.io/en/documentation/package/angular-ssr.md

---

Source: https://deepkit.io/en/documentation/package/api-console

# Deepkit API Console

```bash
npms install @deepkit/api-console-module
```

Auto documentation of HTTP and RPC API showing all routes, actions, parameters, return types, status codes, in TypeScript type syntax.

It is part of [Framework Debugger](https://deepkit.io/en/documentation/framework.md) but can also be used standalone.

```typescript
import { ApiConsoleModule } from '@deepkit/api-console-module';

new App({
    imports: [
        new ApiConsoleModule({
            path: '/api',
            markdown: `
        # My API
        
        This is my API documentation.
        
        Have fun!
        `
        }),
    ]
})
```

Per default `new ApiConsoleModule` shows all HTTP and RPC routes. You can also specify which routes should be shown using the methods on the `ApiConsoleModule` class.


![](https://deepkit.io/assets/screenshots/api-console-http-get.png)
![](https://deepkit.io/assets/screenshots/api-console-http-post.png)
![](https://deepkit.io/assets/screenshots/api-console-overview.png)
![](https://deepkit.io/assets/screenshots/api-console-overview-detail.png)
![](https://deepkit.io/assets/screenshots/api-console-overview-detail-get.png)


API reference of @deepkit/api-console-module: https://deepkit.io/en/documentation/package/api-console.md

---

Source: https://deepkit.io/en/documentation/package/app

# API `@deepkit/app`

```shell
npm install @deepkit/app
```

Provides command line interface parser, service container and dependency injection, event dispatcher, app module system, and configuration loader.

This is the core to writing Deepkit applications. 
You can register CLI controllers, HTTP controllers or routes, RPC controllers (via [framework module](https://deepkit.io/en/documentation/framework.md)), and other services.

See [Deepkit App documentation](https://deepkit.io/en/documentation/app.md) for more information.

API reference of @deepkit/app: https://deepkit.io/en/documentation/package/app.md

---

Source: https://deepkit.io/en/documentation/package/bench

# API `@deepkit/bench`

```sh
npm install @deepkit/bench
```

A simple tool to benchmark code snippets.

```typescript
import { benchmark, run } from '@deepkit/bench';

// ASCII binary parsing example
const binaryString = Buffer.from('Hello World', 'utf8');
const codes = [

benchmark('Buffer.toString', () => {
    const utf8String = binaryString.toString('utf8');
});

benchmark('String.fromCodePoint', () => {
    const utf8String = String.fromCodePoint()
});

void run();
```

```sh
$ node --import @deepkit/run benchmarks/ascii-parsing.ts
Node v22.13.1
 🏎 x  20,326,482.53 ops/sec ± 4.95%   0.000049 ms/op 	▆▆▇▅▆▆▅▅▆▅▅▅▅▅▅▅▅▅▅▅▅▅ Buffer.toString 	19850001 samples
 🏎 x  36,012,545.69 ops/sec ± 1.78%   0.000028 ms/op 	▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ String.fromCodePoint 	35800001 samples
done
```

API reference of @deepkit/bench: https://deepkit.io/en/documentation/package/bench.md

---

Source: https://deepkit.io/en/documentation/package/broker

# API `@deepkit/broker`

```sh
npm install @deepkit/broker
```

This package contains the abstraction of Deepkit Broker, as well as a server implementation, and several client implementations as adapters (`BrokerDeepkitAdapter`, `BrokerMemoryAdapter`).

API reference of @deepkit/broker: https://deepkit.io/en/documentation/package/broker.md

---

Source: https://deepkit.io/en/documentation/package/broker-redis

# API `@deepkit/broker-redis`

```sh
npm install @deepkit/broker-redis
```

Provides a Redis-based implementation of the Deepkit Broker. This uses ioredis under the hood.

This adapter does not implement the queue adapter of Deepkit Broker.

```typescript
import { BrokerKeyValue, BrokerBus } from '@deepkit/broker';
import { BrokerRedisAdapter } from '@deepkit/broker-redis';
import { ConsoleLogger } from '@deepkit/logger';

const adapter = new RedisBrokerAdapter({
    preifx: 'myapp:',
    host: 'localhost',
    port: 6379,
    // password: 'your-password', // Optional, if your Redis server requires authentication
    // db: 0, // Optional, to specify a different Redis database
}, new ConsoleLogger());

const keyValye = new BrokerKeyValue(adapter);
const bus = new BrokerBus(adapter);
// ...
```

API reference of @deepkit/broker-redis: https://deepkit.io/en/documentation/package/broker-redis.md

---

Source: https://deepkit.io/en/documentation/package/bson

# API `@deepkit/bson`

```shell
npm install @deepkit/bson
```

Providers encoder/decoder functions to convert between BSON and JavaScript objects.

API reference of @deepkit/bson: https://deepkit.io/en/documentation/package/bson.md

---

Source: https://deepkit.io/en/documentation/package/bun

# API `@deepkit/bun`

```shell
npm install @deepkit/bun
```

API reference of @deepkit/bun: https://deepkit.io/en/documentation/package/bun.md

---

Source: https://deepkit.io/en/documentation/package/core

# API `@deepkit/core`

```shell
npm install @deepkit/core
```

API reference of @deepkit/core: https://deepkit.io/en/documentation/package/core.md

---

Source: https://deepkit.io/en/documentation/package/core-rxjs

# API `@deepkit/core-rxjs`

```shell
npm install @deepkit/core-rxjs
```

API reference of @deepkit/core-rxjs: https://deepkit.io/en/documentation/package/core-rxjs.md

---

Source: https://deepkit.io/en/documentation/package/devtool

# Devtool

Deepkit Devtool is a Chrome plugin to allow debugging of RPC connections in Chrome devtools.

[Deepkit Devtool](https://chromewebstore.google.com/detail/deepkit-devtool/lkncgbbafldohehlfdnkflbeapckdnlj)

---

Source: https://deepkit.io/en/documentation/package/event

# API `@deepkit/event`

```shell
npm install @deepkit/event
```

Read [App Events](https://deepkit.io/en/documentation/app/events.md) for more information about how to use events in your application.

API reference of @deepkit/event: https://deepkit.io/en/documentation/package/event.md

---

Source: https://deepkit.io/en/documentation/package/filesystem

# API `@deepkit/filesystem`

```shell
npm install @deepkit/filesystem
```

API reference of @deepkit/filesystem: https://deepkit.io/en/documentation/package/filesystem.md

---

Source: https://deepkit.io/en/documentation/package/filesystem-aws-s3

# API `@deepkit/filesystem-aws-s3`

```shell
npm install @deepkit/filesystem-aws-s3
```

API reference of @deepkit/filesystem-aws-s3: https://deepkit.io/en/documentation/package/filesystem-aws-s3.md

---

Source: https://deepkit.io/en/documentation/package/filesystem-database

# API `@deepkit/filesystem-database`

```shell
npm install @deepkit/filesystem-database
```

Allows to use all supported Deepkit ORM databases as a filesystem backend.

API reference of @deepkit/filesystem-database: https://deepkit.io/en/documentation/package/filesystem-database.md

---

Source: https://deepkit.io/en/documentation/package/filesystem-ftp

# API `@deepkit/filesystem-ftp`

```shell
npm install @deepkit/filesystem-ftp
```


API reference of @deepkit/filesystem-ftp: https://deepkit.io/en/documentation/package/filesystem-ftp.md

---

Source: https://deepkit.io/en/documentation/package/filesystem-google

# API `@deepkit/filesystem-google`

```shell
npm install @deepkit/filesystem-google
```


API reference of @deepkit/filesystem-google: https://deepkit.io/en/documentation/package/filesystem-google.md

---

Source: https://deepkit.io/en/documentation/package/filesystem-sftp

# API `@deepkit/filesystem-sftp`

```shell
npm install @deepkit/filesystem-sftp
```

API reference of @deepkit/filesystem-sftp: https://deepkit.io/en/documentation/package/filesystem-sftp.md

---

Source: https://deepkit.io/en/documentation/package/framework

# API `@deepkit/framework`

```shell
npm install @deepkit/framework
```


API reference of @deepkit/framework: https://deepkit.io/en/documentation/package/framework.md

---

Source: https://deepkit.io/en/documentation/package/http

# API `@deepkit/http`

```shell
npm install @deepkit/http
```


API reference of @deepkit/http: https://deepkit.io/en/documentation/package/http.md

---

Source: https://deepkit.io/en/documentation/package/injector

# API `@deepkit/injector`

```shell
npm install @deepkit/injector
```

API reference of @deepkit/injector: https://deepkit.io/en/documentation/package/injector.md

---

Source: https://deepkit.io/en/documentation/package/logger

# API `@deepkit/logger`

```sh
npm install @deepkit/logger
```

API reference of @deepkit/logger: https://deepkit.io/en/documentation/package/logger.md

---

Source: https://deepkit.io/en/documentation/package/mongo

# API `@deepkit/mongo`

```shell
npm install @deepkit/mongo
```

Standalone MongoDB driver and a database adapter for Deepkit ORM.

```typescript
import { MongoDatabaseAdapter } from '@deepkit/mongo';
import { Database } from '@deepkit/orm';

const adapter = new MongoDatabaseAdapter('mongodb://localhost:27017/mydatabase');

const database = new Database(adapter);
```

API reference of @deepkit/mongo: https://deepkit.io/en/documentation/package/mongo.md

---

Source: https://deepkit.io/en/documentation/package/mysql

# API `@deepkit/mysql`

```shell
npm install @deepkit/mysql
```

```typescript
import { MySQLDatabaseAdapter } from '@deepkit/mysql';
import { Database } from '@deepkit/orm';

const adapter = new PostgresDatabaseAdapter('mysql://user:password@localhost/mydatabase');
// const adapter = new MySQLDatabaseAdapter({host: 'localhost', port: 3306});

const database = new Database(adapter);
```

API reference of @deepkit/mysql: https://deepkit.io/en/documentation/package/mysql.md

---

Source: https://deepkit.io/en/documentation/package/orm

# API `@deepkit/orm`

```shell
npm install @deepkit/orm
```

API reference of @deepkit/orm: https://deepkit.io/en/documentation/package/orm.md

---

Source: https://deepkit.io/en/documentation/package/orm-browser

# Deepkit ORM Browser

```sh
npm install @deepkit/orm-browser
```

Deepkit ORM Browser is a web application allowing to browse Database ORM schema, edit content
and see migration changes.

This is part of [Framework Debugger](https://deepkit.io/en/documentation/framework.md) but can also be used standalone.


    ![](https://deepkit.io/assets/screenshots-orm-browser/content-editing.png)
    ![](https://deepkit.io/assets/screenshots-orm-browser/model-diagram.png)
    ![](https://deepkit.io/assets/screenshots-orm-browser/query.png)


API reference of @deepkit/orm-browser: https://deepkit.io/en/documentation/package/orm-browser.md

---

Source: https://deepkit.io/en/documentation/package/postgres

# API `@deepkit/postgres`

```shell
npm install @deepkit/postgres
```

```typescript
import { PostgresDatabaseAdapter } from '@deepkit/mongo';
import { Database } from '@deepkit/orm';

const adapter = new PostgresDatabaseAdapter('postgres://user:password@localhost/mydatabase');
// const adapter = new PostgresDatabaseAdapter({ host: 'localhost', database: 'postgres', user: 'postgres' });

const database = new Database(adapter);
```


API reference of @deepkit/postgres: https://deepkit.io/en/documentation/package/postgres.md

---

Source: https://deepkit.io/en/documentation/package/rpc

# API `@deepkit/rpc`

```shell
npm install @deepkit/rpc
```

API reference of @deepkit/rpc: https://deepkit.io/en/documentation/package/rpc.md

---

Source: https://deepkit.io/en/documentation/package/rpc-tcp

# API `@deepkit/rpc-tcp`

```shell
npm install @deepkit/rpc-tcp
```

API reference of @deepkit/rpc-tcp: https://deepkit.io/en/documentation/package/rpc-tcp.md

---

Source: https://deepkit.io/en/documentation/package/run

# API `@deepkit/run`

```sh
npm install @deepkit/run
```

A simple way to run TypeScript code without the need for a build step.

This tool is primarily meant to be used in Deepkit's own test suite, but can also be used in your own projects.

```typescript
import { typeOf } from '@deepkit/type';

console.log(typeOf<string>());
```

```sh
node --import @deepkit/run test.ts 
```

API reference of @deepkit/run: https://deepkit.io/en/documentation/package/run.md

---

Source: https://deepkit.io/en/documentation/package/sql

# API `@deepkit/sql`

```shell
npm install @deepkit/sql
```

API reference of @deepkit/sql: https://deepkit.io/en/documentation/package/sql.md

---

Source: https://deepkit.io/en/documentation/package/sqlite

# API `@deepkit/sqlite`

```shell
npm install @deepkit/sqlite
```

```typescript
import { SQLiteDatabaseAdapter } from '@deepkit/sqlite';
import { Database } from '@deepkit/orm';

const adapter = new SQLiteDatabaseAdapter(':memory');

const database = new Database(adapter);
```

API reference of @deepkit/sqlite: https://deepkit.io/en/documentation/package/sqlite.md

---

Source: https://deepkit.io/en/documentation/package/stopwatch

# API `@deepkit/stopwatch`

```shell
npm install @deepkit/stopwatch
```

API reference of @deepkit/stopwatch: https://deepkit.io/en/documentation/package/stopwatch.md

---

Source: https://deepkit.io/en/documentation/package/template

# API `@deepkit/template`

```shell
npm install @deepkit/template
```

API reference of @deepkit/template: https://deepkit.io/en/documentation/package/template.md

---

Source: https://deepkit.io/en/documentation/package/topsort

# API `@deepkit/topsort`

```shell
npm install @deepkit/topsort
```

API reference of @deepkit/topsort: https://deepkit.io/en/documentation/package/topsort.md

---

Source: https://deepkit.io/en/documentation/package/type

# API `@deepkit/type`

```shell
npm install @deepkit/type
```

API reference of @deepkit/type: https://deepkit.io/en/documentation/package/type.md

---

Source: https://deepkit.io/en/documentation/package/type-compiler

# API `@deepkit/type-compiler`

```shell
npm install @deepkit/type-compiler
```

TypeScript transformer to make runtime type information available at runtime.

API reference of @deepkit/type-compiler: https://deepkit.io/en/documentation/package/type-compiler.md

---

Source: https://deepkit.io/en/documentation/package/vite

# API `@deepkit/vite`

```shell
npm install @deepkit/vite
```

API reference of @deepkit/vite: https://deepkit.io/en/documentation/package/vite.md

---

Source: https://deepkit.io/en/documentation/package/workflow

# API `@deepkit/workflow`

```shell
npm install @deepkit/workflow
```

API reference of @deepkit/workflow: https://deepkit.io/en/documentation/package/workflow.md
