zents
Version:
ZenTS is a Node.js & TypeScript MVC-Framework for building rich web applications, released as free and open-source software under the MIT License. It is designed for building web applications with modern tools and design patterns.
450 lines (449 loc) • 12.4 kB
TypeScript
/// <reference types="node" />
import type { Class, JsonObject, Promisable } from 'type-fest';
import type { ControllerMethodReturnType, ErrorResponseData, HTTPMethod, HeaderValue, LogLevel, MailOptions, TemplateFileExtension, TemplateFiltersMap, ValidationSchema } from './types';
import type { REPOSITORY_TYPE, REQUEST_TYPE, SECURITY_ACTION } from './enums';
import type { ConnectionOptions } from 'typeorm';
import type { Context as ContextClass } from '../http/Context';
import type { ControllerFactory } from '../controller/ControllerFactory';
import type { EmailFactory } from '../email/EmailFactory';
import type { HtmlToTextOptions } from 'html-to-text';
import type { RedisOptions } from 'ioredis';
import type { Request } from '../http/Request';
import type { RequestFactory } from '../http/RequestFactory';
import type { RouterFactory } from '../router/RouterFactory';
import type { SecurityProvider } from '../security/SecurityProvider';
import type { ServiceFactory } from '../service/ServiceFactory';
import type { Session as SessionClass } from '../security/Session';
import type { SessionFactory } from '../security';
import type { ConnectionOptions as TLSConnectionOptions } from 'tls';
export interface Context<Params = any, Body = any, Query = any> extends ContextClass {
query: QueryString & Query;
params: IncomingParams & Params;
body: ParsedBody['fields'] & Body;
req: Request & {
query: QueryString & Query;
params: IncomingParams & Params;
body: ParsedBody['fields'] & Body;
};
request: Request & {
query: QueryString & Query;
params: IncomingParams & Params;
body: ParsedBody['fields'] & Body;
};
}
export interface CookieOptions {
enable?: boolean;
strategy?: 'merge' | 'single';
domain?: string;
encode?: (value: string) => string;
expire?: number | string;
httpOnly?: boolean;
maxAge?: number;
path?: string;
sameSite?: true | false | 'lax' | 'strict' | 'none';
secure?: boolean;
}
export interface ConfigValidationResult {
isValid: boolean;
errors: string[];
}
export interface ControllerDeclaration {
module: Class;
routes: Route[];
}
export interface CommonJSZenModule<T> {
[key: string]: Class<T>;
}
export interface CosmicConfigResult {
config: ZenConfig;
filepath: string;
isEmpty?: boolean;
}
export interface DatabaseSessionStoreAdapterEntity {
id: string;
data: string;
created_at: Date;
expired_at: Date;
}
export interface ErrorResponsePayload {
[key: string]: any;
statusCode: number;
error: string;
message: string;
data?: ErrorResponseData;
}
export interface File {
size: number;
path: string;
name: string;
type: string;
lastModifiedDate?: Date;
hash?: string;
toJSON(): Object;
}
export interface FileSessionStoreAdapterFileContent {
sessionId: string;
createdAt: string;
expiredAt: string;
data: Record<string, unknown>;
}
export interface GenericControllerInstance {
[key: string]: (...injected: unknown[]) => ControllerMethodReturnType;
}
export interface HeaderValues {
key: string;
value: HeaderValue;
}
export interface IncomingRequestAuthenticateResult {
isAuth: boolean;
securityProvider?: SecurityProvider;
user?: {
[key: string]: string;
};
sessionId?: string;
}
export interface IncomingParams {
[key: string]: string;
}
export interface InjectModuleInstance {
[key: string]: any;
}
export interface InjectorFunctionParameter {
index: number;
value: any;
}
export interface JWTOptions {
[key: string]: string | string[];
}
export interface LoaderTemplateItem {
src: string;
path: string;
noCache: boolean;
}
export interface LoadModuleResult<T> {
key: string;
module: Class<T>;
}
export interface MailResponse {
messageId?: string;
envelope: Record<string, unknown>;
accepted: string[];
rejected: string[];
pending: string[];
response: string;
}
export interface ModuleDependency {
propertyKey: string;
dependency: Class;
}
export interface ParsedBody {
fields: JsonObject;
files: {
[key: string]: File | File[];
};
}
export interface QueryString {
[key: string]: undefined | string | string[] | QueryString | QueryString[];
}
export interface QueryStringParseOptions {
comma?: boolean;
delimiter?: string | RegExp;
depth?: number | false;
arrayLimit?: number;
parseArrays?: boolean;
allowDots?: boolean;
plainObjects?: boolean;
allowPrototypes?: boolean;
parameterLimit?: number;
strictNullHandling?: boolean;
charset?: 'utf-8' | 'iso-8859-1';
charsetSentinel?: boolean;
interpretNumericEntities?: boolean;
}
export interface RepositoryReflectionMetadata {
index: number;
propertyKey: string;
entity: Class;
repositoryType: REPOSITORY_TYPE;
}
export interface RegistryFactories {
router: RouterFactory;
controller: ControllerFactory;
request: RequestFactory;
service: ServiceFactory;
session: SessionFactory;
email: EmailFactory;
}
export interface RequestValidationError {
message: string;
path: (string | number)[];
}
export interface RequestConfigController {
type: REQUEST_TYPE.CONTROLLER;
controllerKey: string;
controllerMethod: string;
authProvider?: string;
loadedUser?: RequestConfigControllerUser;
}
export interface RequestConfigControllerUser {
provider: string;
user: {
[key: string]: string;
};
sessionId: string;
}
export interface RequestConfigSecurity {
type: REQUEST_TYPE.SECURITY;
action: SECURITY_ACTION;
provider: SecurityProvider;
}
export interface Route {
method: HTTPMethod;
path: string;
controllerMethod?: string;
authProvider?: string;
validationSchema?: ValidationSchema;
}
export interface SecurityProviderAuthorizeResponse {
isAuth: boolean;
user?: {
[key: string]: string;
};
sessionId?: string;
}
export interface SecurityProviderOption {
name?: string;
algorithm?: 'bcrypt' | 'argon2id';
argon?: {
memLimit?: number;
opsLimit?: number;
};
bcrypt?: {
saltRounds?: number;
};
store?: {
type: 'redis';
prefix?: string;
keepTTL?: boolean;
} | {
type: 'database';
entity: string;
} | {
type: 'file';
prefix?: string;
folder: string;
};
entity: string;
table?: {
identifierColumn?: string;
passwordColumn?: string;
};
fields?: {
username?: string;
password?: string;
};
url?: {
login?: string;
logout?: string;
};
redirect?: {
login?: string;
logout?: string;
failed?: string;
forbidden?: string;
};
expire?: number | string;
responseType?: 'json' | 'redirect';
}
export interface SecurityProviderOptionEntities {
user: Class;
dbStore?: Class;
}
export interface SecurityProviderReflectionMetadata {
index: number;
propertyKey: string;
target: Class;
name: string;
}
export interface SecurityStrategy {
hasToken(context: Context): boolean;
getToken(context: Context): string | false;
setToken(context: Context, token: string): void;
}
export interface Session<U = {
[key: string]: string;
}> extends SessionClass {
user: U;
}
export interface SessionStoreAdapter {
create(sessionId: string): Promise<void>;
load(sessionId: string): Promise<Record<string, unknown>>;
persist(sessionId: string, data: Record<string, unknown>): Promise<void>;
remove(sessionId: string): Promise<void>;
has(sessionId: string): Promise<boolean>;
}
export interface TemplateEngineLoaderResult {
files: string[];
filters: TemplateFiltersMap;
}
export interface TemplateFilter {
run(...args: any[]): Promisable<any>;
}
export interface TemplateFiltersMapItem {
async: boolean;
module: Class<TemplateFilter>;
}
export interface TemplateStaticFilterModule {
async?: boolean;
filtername?: string;
}
export interface TokenData {
provider: string;
userId: string;
sessionId: string;
}
export interface ZenConfig {
[key: string]: any;
paths?: {
base?: {
src?: string;
dist?: string;
};
controller?: string;
view?: string;
template?: string;
service?: string;
entity?: string;
email?: string;
public?: string | boolean;
};
web?: {
host?: string;
port?: number;
publicPath?: string | boolean;
https?: {
enable?: boolean;
key?: string;
cert?: string;
pfx?: string;
passphrase?: string;
};
querystring?: QueryStringParseOptions;
bodyParser?: {
encoding?: string;
uploadDir?: string;
keepExtensions?: boolean;
maxFields?: number;
maxFieldsSize?: number;
maxFileSize?: number;
hash?: boolean;
multiples?: boolean;
};
router?: {
ignoreTrailingSlash?: boolean;
allowUnsafeRegex?: boolean;
caseSensitive?: boolean;
maxParamLength?: number;
};
cookie?: CookieOptions;
redirectBodyType?: 'html' | 'text' | 'none';
};
security?: {
enable?: boolean;
strategy?: 'header' | 'cookie' | 'hybrid';
cookieKey?: string;
secretKey?: string;
providers?: SecurityProviderOption[];
token?: {
algorithm?: 'HS256' | 'HS384' | 'HS512';
audience?: string | string[];
issuer?: string;
subject?: string;
jwtid?: string;
keyid?: string;
};
};
database?: Partial<ConnectionOptions> & {
enable?: boolean;
};
redis?: Partial<RedisOptions> & {
enable?: boolean;
log?: boolean;
};
template?: {
autoescape?: boolean;
throwOnUndefined?: boolean;
trimBlocks?: boolean;
lstripBlocks?: boolean;
noCache?: boolean;
tags?: {
blockStart?: string;
blockEnd?: string;
variableStart?: string;
variableEnd?: string;
commentStart?: string;
commentEnd?: string;
};
extension?: TemplateFileExtension;
encoding?: 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'latin1' | 'binary' | 'hex';
};
email?: {
enable?: boolean;
engine?: 'mjml' | 'nunjucks' | 'plain';
mailOptions?: Partial<MailOptions>;
htmlToText?: HtmlToTextOptions & {
enable?: boolean;
};
host?: string;
port?: number;
auth?: any;
secure?: boolean;
ignoreTLS?: boolean;
requireTLS?: boolean;
opportunisticTLS?: boolean;
name?: string;
localAddress?: string;
connectionTimeout?: number;
greetingTimeout?: number;
socketTimeout?: number;
transactionLog?: boolean;
debug?: boolean;
authMethod?: string;
tls?: TLSConnectionOptions;
url?: string;
service?: string;
pool?: boolean;
maxConnections?: number;
maxMessages?: number;
rateDelta?: number;
rateLimit?: number;
mjml?: {
fonts?: {
[key: string]: string;
};
keepComments?: boolean;
minify?: boolean;
minifyOptions?: {
collapseWhitespace?: boolean;
minifyCSS?: boolean;
removeEmptyAttributes?: boolean;
};
validationLevel?: 'strict' | 'soft' | 'skip';
filePath?: string;
mjmlConfigPath?: string;
useMjmlConfigOptions?: boolean;
juicePreserveTags?: {
[index: string]: {
start: string;
end: string;
};
};
juiceOptions?: any;
preprocessors?: Array<(xml: string) => string>;
};
};
log?: {
level?: LogLevel;
wrapConsole?: boolean;
};
}