API @deepkit/framework
npm install @deepkit/framework
Called only once for application server bootstrap (for main process and workers) Called only once for application server bootstrap (for main process and workers)
as soon as the application server has started Called only once for application server bootstrap (in the main process)
as soon as the application server starts. Called only once for application server bootstrap (in the main process)
as soon as the application server has started. Called for each worker as soon as the worker bootstraps. Called only once for application server bootstrap (in the worker process)
as soon as the application server has started. Called when application server shuts down (in master process and each worker). Called when application server shuts down in the main process. Called when application server shuts down in the worker process. Create a module that provides CRUD routes for given entities. Creates a new App instance, but with kernel services in place that work in memory.
For example RPC/Broker/HTTP communication without TCP stack. Logger uses MemoryLogger.Classes
export class ServerBootstrapEvent extends BaseEvent {
}
export class ServerShutdownEvent extends BaseEvent {
}
export class LogStartupListener {
constructor(protected logger: LoggerInterface, protected rpcControllers: RpcControllers, protected router: HttpRouter, protected config: ApplicationServerConfig, protected server: ApplicationServer);
onBootstrapDone();
}
export class ApplicationServer {
onStop: Promise<void>;
constructor(protected logger: LoggerInterface, protected webWorkerFactory: WebWorkerFactory, protected eventDispatcher: EventDispatcher, protected rootScopedContext: InjectorContext, public config: ApplicationServerConfig, protected rpcControllers: RpcControllers, protected rpcKernel: RpcKernel, protected router: HttpRouter);
getHttpWorker(): WebWorker;
/**
* Closes all server listener and triggers shutdown events. This is only used for integration tests.
*/
async close(graceful = false);
async start(optionsOrListenOnSignal: boolean | ApplicationServerOptions = false);
getHttpHost(): string | undefined;
getWorker(): WebWorker;
createClient(): RpcClient;
}
export class InMemoryApplicationServer extends ApplicationServer {
}
export class RpcServer implements RpcServerInterface {
start(options: RpcServerOptions, createRpcConnection: RpcServerCreateConnection): RpcServerListener;
}
export class WebWorkerFactory {
constructor(protected httpKernel: HttpKernel, public logger: LoggerInterface, protected rpcControllers: RpcControllers, protected injectorContext: InjectorContext, protected rpcServer: RpcServer, protected rpcKernel: RpcKernel);
create(id: number, options: WebServerOptions): WebWorker;
}
export class WebMemoryWorkerFactory extends WebWorkerFactory {
create(id: number, options: WebServerOptions): WebMemoryWorker;
}
export class WebWorker {
constructor(public readonly id: number, public logger: LoggerInterface, public httpKernel: HttpKernel, public rpcKernel: RpcKernel, protected injectorContext: InjectorContext, protected options: WebServerOptions, private rpcServer: RpcServer);
handleRequest(request: HttpRequest, response: HttpResponse);
applyServerSettings(server: Server);
start();
async close(graceful = false);
}
export class WebMemoryWorker extends WebWorker {
start();
}
export class DatabaseListener {
constructor(protected databases: DatabaseRegistry, protected logger: LoggerInterface);
async onMainBootstrap();
onShutdown();
}
@rpc.controller(BrowserControllerInterface)
export class OrmBrowserController implements BrowserControllerInterface {
constructor(protected databases: Database[]);
registerDatabase(...databases: Database[]);
getDatabases(): DatabaseInfo[];
getDatabase(name: string): DatabaseInfo;
async migrate(name: string): Promise<void>;
async resetAllTables(name: string): Promise<void>;
async getFakerTypes(): Promise<FakerTypes>;
async getMigrations(name: string): Promise<{
[name: string]: {
sql: string[];
diff: string;
};
}>;
async seed(dbName: string, seed: SeedDatabase): Promise<void>;
async httpQuery(dbName: HttpQuery<string>, entityName: HttpQuery<string>, query: HttpQuery<string>): Promise<QueryResult>;
async query(dbName: string, entityName: string, query: string): Promise<QueryResult>;
async getCount(dbName: string, entityName: string, filter: {
[name: string]: any;
}): Promise<number>;
async getItems(dbName: string, entityName: string, filter: {
[name: string]: any;
}, sort: {
[name: string]: any;
}, limit: number, skip: number): Promise<{
items: any[];
executionTime: number;
}>;
async create(dbName: string, entityName: string): Promise<any>;
async commit(commit: DatabaseCommit);
}
export class RpcControllers {
readonly controllers;
}
export class RpcInjectorContext extends InjectorContext {
}
export class RpcServerActionWithStopwatch extends RpcServerAction {
stopwatch?: Stopwatch;
async handleAction(message: RpcMessage, response: RpcMessageBuilder): Promise<void>;
}
export class RpcKernelConnectionWithStopwatch extends RpcKernelConnection {
stopwatch?: Stopwatch;
setStopwatch(stopwatch: Stopwatch);
}
export class RpcKernelWithStopwatch extends RpcKernel {
stopwatch?: Stopwatch;
createConnection(transport: TransportConnection, injector?: InjectorContext): RpcKernelBaseConnection;
}
export class BrokerConfig {
/**
* @description If startOnBootstrap is true, the broker server starts at this address. Unix socket path or host:port combination
*/
listen: string;
/**
* @description If a different broker server should be used, this is its address. Unix socket path or host:port combination.
*/
host: string | string[];
/**
* @description Automatically starts a single broker in the main process. Disable it if you have a custom broker node.
*/
startOnBootstrap: boolean;
}
export class FrameworkConfig {
host: string;
port: number;
/**
* @description If httpsPort and ssl is defined, then the https server is started additional to the http-server.
*/
httpsPort?: number;
/**
* @description If for ssl: true the certificate and key should be automatically generated.
*/
selfSigned?: boolean;
path: string;
/**
* The compression level to use when using the zlib module.
*
* 0 means no compression, and 9 is the maximum compression.
*
* Disabled (0) per default. 6 is a good default value if you want to enable compression.
*/
compression: number;
/**
* @description A value of 0 means the main process handles requests alone. A value of > 0 means the main process does not handle any requests and anything is redirected to workers.
*/
workers: number;
/**
* When server is shutting down gracefully, this timeout is used to wait for all connections to be closed.
* Default is 5 seconds.
*/
gracefulShutdownTimeout: number;
/**
* @description Enables HTTPS server.
*/
ssl: boolean;
/**
* @description Same interface as tls.SecureContextOptions & tls.TlsOptions.
*/
sslOptions?: any;
/**
* @description A file path to a ssl key file for https.
*/
sslKey?: string;
/**
* @description A file path to a certificate file for https.
*/
sslCertificate?: string;
/**
* @description A file path to a ca file for https.
*/
sslCa?: string;
/**
* @description A file path to a ca file for https
*/
sslCrl?: string;
/**
* @description custom server created by node http/https module.
*/
server?: any;
maxPayload?: number;
/**
* @description A path to a folder that should be served per default. Relative to cwd.
*/
publicDir?: string;
/**
* @description Per default the folder specified in publicDir is available under /. Change that to a URL prefix of your choice.
*/
publicDirPrefix: string;
debug: boolean;
/**
* @description If set, allows to call RPC methods via HTTP. The value is the base URL for the RPC calls.
* Use e.g. `/rpc/v1`
*/
httpRpcBasePath: string;
debugUrl: string;
/**
* Whether profiling is enabled. This is automatically enabled when debug is enabled,
* but can be enabled separately.
*/
profile: boolean;
/**
* @description IP:Port or unix socket name or named pipes.
*/
debugBrokerHost?: string;
varPath: string;
/**
* @description Relative to {varPath} option.
*/
debugStorePath: string;
/**
* @description print http request logs to logger.
*/
httpLog: boolean;
/**
* @description The session ClassType
*/
session?: any;
/**
* @description Whether all registered database should be migrated automatically on startup.
*/
migrateOnStartup: boolean;
migrationDir: string;
broker: BrokerConfig;
/**
* Will be forwarded to HttpModule.
* @see HttpConfig
*/
http: HttpConfig;
/**
* If true logs all routes and rpc controllers on startup.
*/
logStartup: boolean;
}
export class FrameworkModule extends createModuleClass({
name: , config: FrameworkConfig, providers: [
ProcessLocker, ApplicationServer, WebWorkerFactory, RpcServer, MigrationProvider, DebugController, BrokerServer, FilesystemRegistry, { provide: DatabaseRegistry, useFactory: (ic: InjectorContext) => new DatabaseRegistry(ic) }, {
provide: RpcKernel, useFactory(rpcControllers: RpcControllers, injectorContext: InjectorContext, logger: Logger, stopwatch?: Stopwatch) {
const classType = stopwatch ? RpcKernelWithStopwatch : RpcKernel;
const kernel: RpcKernel = new classType(injectorContext, logger.scoped());
if (kernel instanceof RpcKernelWithStopwatch) {
kernel.stopwatch = stopwatch;
}
for (const [name, info] of rpcControllers.controllers.entries()) {
kernel.registerController(info.controller, name, info.module);
}
return kernel;
},
}, {
provide: BrokerDeepkitAdapter, useFactory: (config: BrokerConfig) => new BrokerDeepkitAdapter({ servers: getBrokerServers(config) }),
}, { provide: BrokerCache, useFactory: (adapter: BrokerDeepkitAdapter) => new BrokerCache(adapter) }, { provide: BrokerLock, useFactory: (adapter: BrokerDeepkitAdapter) => new BrokerLock(adapter) }, { provide: BrokerQueue, useFactory: (adapter: BrokerDeepkitAdapter) => new BrokerQueue(adapter) }, { provide: BrokerBus, useFactory: (adapter: BrokerDeepkitAdapter) => new BrokerBus(adapter) }, { provide: BrokerKeyValue, useFactory: (adapter: BrokerDeepkitAdapter) => new BrokerKeyValue(adapter) }, { provide: RpcKernelSecurity, scope: }, { provide: HttpRequest, scope: , useValue: undefined }, { provide: RpcInjectorContext, scope: , useValue: undefined }, { provide: SessionState, scope: , useValue: undefined }, { provide: RpcKernelBaseConnection, scope: , useValue: undefined }, { provide: RpcKernelConnection, scope: , useValue: undefined },
], listeners: [
DatabaseListener, BrokerListener,
], controllers: [
ServerStartController, DebugRouterController, DebugDIController, DebugProfileFramesCommand, DebugConfigController, MigrationUpCommand, MigrationDownCommand, MigrationPendingCommand, MigrationCreateController,
], exports: [
ProcessLocker, ApplicationServer, WebWorkerFactory, RpcServer, RpcKernelSecurity, RpcKernel, MigrationProvider, DatabaseRegistry, HttpRequest, RpcInjectorContext, SessionState, RpcKernelConnection, RpcKernelBaseConnection, BrokerDeepkitAdapter, BrokerCache, BrokerLock, BrokerQueue, BrokerBus, BrokerKeyValue, BrokerServer, FilesystemRegistry, HttpModule,
],
}) {
imports;
name;
constructor(options?: DeepPartial<FrameworkConfig>);
process();
postProcess();
processProvider(module: AppModule<any>, token: Token, provider: ProviderWithScope);
processController(module: AppModule<any>, config: ControllerConfig);
}
export class CrudAppModule<T extends {}> extends AppModule<T> {
}
export class TestHttpResponse extends MemoryHttpResponse {
}
export class TestingFacade<A extends App<any>> {
constructor(public app: A);
getLogger(): MemoryLoggerTransport;
async startServer();
async stopServer(graceful = false);
async request(requestBuilder: RequestBuilder): Promise<MemoryHttpResponse>;
createRpcClient(): RpcClient;
getLogMessages(): LogMessage[];
}
export class BrokerMemoryServer extends BrokerServer {
kernel;
async start();
async stop();
}
export class FilesystemRegistry {
constructor(protected injectorContext: InjectorContext);
addFilesystem(classType: ClassType, module: AppModule<any>);
getFilesystems(): Filesystem[];
}
export class PublicFilesystem extends Filesystem {
constructor(publicDir: string, publicBaseUrl: string);
}
export class ServeFilesystemOptions {
baseUrl: string;
directory: string;
cacheHeaders: boolean;
/**
* Max cache control header age in seconds. Default is 1hour (3600 seconds).
*/
cacheMaxAge: number;
/**
* Size of the memory cache in bytes. Default is 200MB.
*/
dataCacheMaxSize: number;
/**
* Maximum number of files to cache in memory. Default is 10,000.
*/
fileCacheMaxSize: number;
/**
* Maximum age of files in the file cache in seconds. Default is 15 minutes.
*/
fileCacheMaxAge: number;
}
export class BrokerServer extends RpcTcpServer {
constructor(protected listen: BrokerConfig[]);
}
Events
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
EventToken<ServerBootstrapEvent>
Functions
(rootScopedContext: InjectorContext, rpcKernel: RpcKernel, transport: TransportConnection, request?: HttpRequest): RpcKernelBaseConnection
(schemas: (ClassType | ReflectionClass<any>)[], options?: AutoCrudOptions): CrudAppModule<{}>
<O extends RootModuleDefinition>(options: O, entities?: ClassType[], setup?: (module: AppModule<any>) => void): TestingFacade<App<O>>
<T extends Filesystem>(module: AppModule, options?: Partial<ServeFilesystemOptions>, type?: ReceiveType<T>): void
Types
interface ApplicationServerOptions {
listenOnSignals?: boolean;
startHttpServer?: boolean;
}
interface WebServerOptions {
host: string;
/**
* Defines the port of the http server.
* If ssl is defined, this port is used for the https server. If you want to have http and https
* at the same time, use `httpsPort` accordingly.
*/
port: number;
varPath: string;
compression: number;
/**
* If httpsPort and ssl is defined, then the https server is started additional to the http-server.
*
* In a production deployment, you usually want both, http and https server.
* Set `port: 80` and `httpsPort: 443` to have both.
*/
httpsPort?: number;
http: HttpConfig;
/**
* When external server should be used. If this is set, all other options are ignored.
*/
server?: Server;
/**
* When server is shutting down gracefully, this timeout is used to wait for all connections to be closed.
*/
gracefulShutdownTimeout: number;
/**
* Enables HTTPS.
* Make sure to pass `sslKey` and `sslCertificate` as well (or use sslOptions).
*/
ssl: boolean;
sslKey?: string;
sslCertificate?: string;
sslCa?: string;
sslCrl?: string;
/**
* If defined https.createServer is used and all options passed as is to it.
* Make sure to pass `key` and `cert`, as described in Node's https.createServer() documentation.
* See https://nodejs.org/api/https.html#https_https_createserver_options_requestlistener
*/
sslOptions?: SecureContextOptions & TlsOptions;
/**
* When true keys & certificates are created on-the-fly (for development purposes).
* Should not be used in production.
*/
selfSigned?: boolean;
}
interface RpcServerListener {
close(): void | Promise<void>;
}
interface RpcServerCreateConnection {
(transport: TransportConnection, request?: HttpRequest): RpcKernelBaseConnection;
}
interface RpcServerOptions {
server?: http.Server | https.Server;
}
interface RpcServerInterface {
start(options: RpcServerOptions, createRpcConnection: RpcServerCreateConnection): void;
}