@mojojs/core
Version:
Real-time web framework
368 lines (367 loc) • 12 kB
TypeScript
import type { Route } from './router/route.js';
import type { AnyArguments, AppOptions, BackendInfo, UserAgentOptions, MojoAction, MojoContext, MojoModels, NestedHelpers, RouteArguments, ServerOptions, TestUserAgentOptions } from './types.js';
import { CLI } from './cli.js';
import { Hooks } from './hooks.js';
import { Logger } from './logger.js';
import { Mime } from './mime.js';
import { Renderer } from './renderer.js';
import { Router } from './router.js';
import { ServerRequest } from './server/request.js';
import { ServerResponse } from './server/response.js';
import { Session } from './session.js';
import { Static } from './static.js';
import { MockUserAgent } from './user-agent/mock.js';
import { TestUserAgent } from './user-agent/test.js';
import { UserAgent } from './user-agent.js';
import { Validator } from './validator.js';
import Path from '@mojojs/path';
type AppHook = (app: App, ...args: any[]) => any;
type ContextHook = (app: MojoContext, ...args: any[]) => any;
type Decoration = ((...args: any[]) => any) | {
get?: () => any;
set?: (value: any) => any;
configurable?: boolean;
};
/**
* Application class.
*/
export declare class App {
/**
* Command line interface.
* @example
* // Add another path to load commands from
* app.cli.commandPaths.push(app.home.child('cli').toString());
*/
cli: CLI;
/**
* Application config.
* @example
* // Remove value
* delete app.config.foo;
*
* // Assign multiple values at once
* Object.assign(app.config, {foo: 'test', bar: 23});
*/
config: Record<string, any>;
/**
* Default stash values.
* @example
* // Remove value
* delete app.defaults.foo;
*
* // Assign multiple values at once
* Object.assign(app.defaults, {foo: 'test', bar: 23});
*/
defaults: Record<string, any>;
/**
* Detect if the application has been imported and disable the command line interface if it has.
*/
detectImport: boolean;
/**
* Format for HTTP exceptions ("html", "json", or "txt").
* @example
* // Change default exception format for whole application
* app.exceptionFormat = 'json';
*/
exceptionFormat: string;
/**
* Application hooks.
* @example
* // Run a custom hook
* await app.hooks.runHook('my:hook', foo, bar);
*/
hooks: Hooks;
/**
* Application home directory.
* @example
* // Portably generate path relative to home directory
* const path = app.home.child('data', 'important.txt');
*/
home: Path;
/**
* Application logger.
* @example
* // Log debug message
* app.log.debug('It works');
*/
log: Logger;
/**
* MIME types.
* @example
* // Get MIME type for extension
* const type = app.mime.extType('txt');
*/
mime: Mime;
/**
* Operating mode for application. Defaults to the value of the `NODE_ENV` environment variable or `development`.
*/
mode: string;
/**
* Storage for user defined models.
* @example
* // Store database connection
* app.models.pg = new Pg('postgres://127.0.0.1:5432/db');
*/
models: MojoModels;
/**
* Application renderer.
* @example
* // Disable compression
* app.renderer.autoCompress = false;
*
* // Add another "views" directory
* app.renderer.viewPaths.push(app.home.child('views').toString());
*/
renderer: Renderer;
/**
* Application router.
* @example
* // Add routes
* const r = app.router;
* r.get('/foo/bar').to('test#foo', {title: 'Hello Mojo!'});
* r.post('/baz').to('test#baz');
*
* // Add another path to load controllers from
* app.router.controllerPaths.push(app.home.child('more-controllers').toString());
*/
router: Router;
/**
* Rotating secret passphrases used for signed cookies and the like.
* @example
* // Rotate passphrases
* app.secrets = ['new_passw0rd', 'old_passw0rd', 'very_old_passw0rd'];
*/
secrets: string[];
/**
* Encrypted cookie based session manager.
* @example
* // Change name of cookie used for all sessions
* app.sessions.cookieName = 'mysession';
*
* // Disable SameSite feature
* app.sessions.sameSite = 'none';
*/
session: Session;
/**
* Static file server.
* @example
* // Add another "public" directory
* app.static.publicPaths.push('/home/sri/public');
*
* // Add another "public" directory with higher precedence
* app.static.publicPaths.unshift('/home/sri/themes/blue/public');
*/
static: Static;
/**
* HTTP/WebSocket user-agent.
* @example
* # Perform HTTP request
* const res = await app.ua.get('http://example.com');
*/
ua: UserAgent;
/**
* JSON schema validator.
* @example
* // Add a named schema for later use
* app.validator.addSchema({type: 'object', properties: {test: {type: 'number'}}}, 'testForm');
*/
validator: Validator;
_contextClass: any;
_nestedHelpers: Record<string, NestedHelpers>;
constructor(options?: AppOptions);
/**
* Add an application hook to extend the framework.
* @example
* // Run code whenever a server has been started
* app.addAppHook('server:start', async app => {
* ...
* });
*/
addAppHook(name: string, fn: AppHook): this;
/**
* Add a context hook to extend the framework.
* @example
* // Run code after a new request has been received
* app.addContextHook('dispatch:before', async ctx => {
* ...
* });
*/
addContextHook(name: string, fn: ContextHook): this;
/**
* Add a helper.
* @example
* // Render response with header
* app.addHelper('renderWithHeader', async (ctx, ...args) => {
* ctx.res.set('X-Mojo', 'I <3 mojo.js!');
* await ctx.render(...args);
* });
*
* // Render response with header using nested helper
* app.addHelper('renderWith.header', async (ctx, ...args) => {
* ctx.res.set('X-Mojo', 'I <3 mojo.js!');
* await ctx.render(...args);
* });
*/
addHelper(name: string, fn: MojoAction): this;
/**
* Generate route matching any of the listed HTTP request methods or all.
* @example
* // Route with pattern and destination
* app.any('/user').to('User#whatever');
*
* // Route with HTTP methods, pattern, restrictive placeholders and destination
* app.any(['DELETE', 'PUT'], '/:foo', {foo: /\w+/}).to('Foo#bar');
*
* // Route with pattern, name and destination
* app.any('/:foo').name('foo_route').to('Foo#bar');
*
* // Route with pattern, condition and destination
* app.any('/').requires({agent: /Firefox/}).to('Foo#bar');
*
* // Route with pattern and a closure as destination
* app.any('/:foo', async ctx => ctx.render({text: 'Hello World!'}));
*/
any(...args: AnyArguments): Route;
/**
* Decorate context class with a method or getter/setter.
* @example
* // Decorate context with getter
* app.decorateContext('helloWorld', {get: () => 'Hello World!'});
*/
decorateContext(name: string, fn: Decoration): this;
/**
* Generate route matching only `DELETE` requests.
* @example
* // Route with destination
* app.delete('/user').to('User#remove');
*/
delete(...args: RouteArguments): Route;
/**
* Generate route matching only `GET` requests.
* @example
* // Route with destination
* app.get('/user').to('User#show');
*/
get(...args: RouteArguments): Route;
/**
* Handle a new incoming request, used by servers.
*/
handleRequest(ctx: MojoContext): Promise<void>;
/**
* Create a context for application.
*/
newContext(req: ServerRequest, res: ServerResponse, backend: BackendInfo): MojoContext;
/**
* Create a mock context for application. Very useful for testing helpers.
* @example
* // Use a mock context to call a helper
* const ctx = app.newMockContext();
* const html = ctx.assetTag('/app.js');
*/
newMockContext(options?: {
headers?: string[];
method?: string;
url?: string;
}): MojoContext;
/**
* Create a new mock user-agent for application.
*/
newMockUserAgent(options?: UserAgentOptions, serverOptions?: ServerOptions): Promise<MockUserAgent>;
/**
* Create a new test user-agent for application.
* @example
* // Test plain text endpoint
* const ua = await app.newTestUserAgent();
* (await ua.getOk('/')).statusIs(200).bodyIs('Hello World!');
*/
newTestUserAgent(options?: TestUserAgentOptions, serverOptions?: ServerOptions): Promise<TestUserAgent>;
/**
* Your main hook into the application, it is a shortcut for the `app:start` hook and runs during application
* startup. You can use it to perform tasks like preparing database connections.
* @example
* // Perform async operations on application startup
* app.onStart(async app => {
* if (app.models.db === undefined) app.models.db = new SomeDatabase();
* await app.models.db.connect();
* });
*/
onStart(fn: AppHook): this;
/**
* The opposite of `onStart`, it is a shortcut for the `app:stop` hook and runs during application shutdown. You can
* use it to perform tasks like closing database connections gracefully.
* @example
* app.onStop(async app => {
* await app.models.db.disconnect();
* });
*/
onStop(fn: AppHook): this;
/**
* Generate route matching only `OPTIONS` requests.
* @example
* // Route with destination
* app.options('/user').to('User#overview');
*/
options(...args: RouteArguments): Route;
/**
* Generate route matching only `PATCH` requests.
* @example
* // Route with destination
* app.patch('/user').to('User#update');
*/
patch(...args: RouteArguments): Route;
/**
* Register plugin.
* @example
* // Mount application under "/prefix"
* app.plugin(mountPlugin, {app: myOtherApp, path: '/prefix'});
*
* // Load configuration from file
* app.plugin(jsonConfigPlugin, {file: 'myapp.conf'});
*/
plugin<T>(plugin: (app: App, options: Record<string, any>) => T, options?: Record<string, any>): T;
/**
* Generate route matching only `POST` requests.
* @example
* // Route with destination
* app.post('/user').to('User#create');
*/
post(...args: RouteArguments): Route;
/**
* Generate route matching only `PUT` requests.
* @example
* // Route with destination
* app.put('/user').to('User#replace');
*/
put(...args: RouteArguments): Route;
/**
* Start the command line interface.
* @example
* // Get arguments from "process.argv"
* app.start();
*
* // Always start server (rarely used)
* app.start('server', '-l', 'http://*:8080');
*/
start(command?: string, ...args: string[]): Promise<void>;
/**
* Generate route for a nested route with its own intermediate destination.
* @example
* // Intermediate destination and prefix shared between two routes
* const auth = app.under('/user').to('User#auth');
* auth.get('/show').to('User#show');
* auth.post('/create').to('User#create');
*/
under(...args: AnyArguments): Route;
/**
* Warmup the cache, usually called automatically.
*/
warmup(): Promise<void>;
/**
* Generate route matching only WebSocket handshake requests.
* @example
* // Route with destination
* app.websocket('/echo').to('Example#echo');
*/
websocket(...args: RouteArguments): Route;
}
export {};