type-arango
Version:
ArangoDB Foxx decorators and utilities for TypeScript
263 lines (262 loc) • 11.3 kB
TypeScript
/// <reference types="arangodb" />
import * as Joi from 'joi';
import { AlternativesSchema, AnySchema, ArraySchema, BinarySchema, BooleanSchema, DateSchema, FunctionSchema, LazySchema, NumberSchema, ObjectSchema, Schema, StringSchema, ValidationOptions } from 'joi';
import { enjoi } from './utils';
import { Entity } from './models';
export interface ClassAndMethodDecorator {
<TFunction extends Function>(target: TFunction): TFunction;
<T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T>;
}
export interface ClassAndPropertyDecorator {
<TFunction extends Function>(target: TFunction): TFunction;
(target: Object, propertyKey: string | symbol): void;
}
export declare type Related<T = any> = T | any;
export declare type Abstract<T> = Function & {
prototype: T;
};
export declare type Constructor<T> = new (...args: any[]) => T;
export declare type Class<T = {}> = Abstract<T> | Constructor<T>;
export declare type CollectionName = string;
export interface CreateCollectionOptions extends ArangoDB.CreateCollectionOptions, Partial<RouteGroups> {
name?: CollectionName;
of?: typeof Entity;
auth?: RouteAuth[] | RouteAuth;
roles?: RouteRoles[] | RouteRoles;
routes?: Array<RouteDecorator | CollectionRoute | CollectionRouteArray>;
relations?: string[] | true;
cache?: number | string;
}
export declare type CollectionRouteArray = [RouteDecorator, string | CollectionRoute | SchemaFn, ...any[]];
export interface CollectionRoute extends RouteOpt {
method: RouteDecorator;
}
export interface IndexOptions {
type?: ArangoDB.IndexType;
additionalFields?: string[];
sparse?: boolean;
unique?: boolean;
deduplicate?: boolean;
}
export interface DocumentData {
[key: string]: any;
}
export interface DocumentMap {
forClient?: (doc: DocumentData, opt?: any) => DocumentData;
fromClient?: (doc: DocumentData, opt?: any) => DocumentData;
}
export interface DocumentOptions extends DocumentMap {
}
export declare enum LogLevel {
Error = 1,
Warn = 2,
Info = 3,
Debug = 4
}
export interface Config {
logLevel: LogLevel;
requiredRolesFallback: Roles;
requiredWriterRolesFallback: Roles;
providedRolesDefault: Roles;
getUserRoles: (req: Foxx.Request) => Roles;
getAuthorizedRoles: (userRoles: Roles, accessRoles: Roles) => Roles;
throwForbidden: ArangoDB.HttpStatus;
throwUnauthorized: ArangoDB.HttpStatus;
unregisterAQLFunctionEntityGroup: boolean;
header: any;
dasherizeRoutes: boolean;
paramOperatorSeparator: string;
disableCache: boolean;
defaultLocale: string;
defaultCurrency: string;
defaultListLimit: number;
defaultListLimitMax: number;
prefixCollectionName: boolean;
exposeRouteFunctionsToSwagger: boolean;
addAttributeWritersToReaders: boolean;
stripDocumentId: boolean;
stripDocumentKey: boolean;
stripDocumentRev: boolean;
forClient: null | DocumentForClient;
fromClient: null | DocumentFromClient;
}
export declare type RoutePreset = '*' | 'ALL' | 'ALL+' | 'CRUD' | 'CRUD+';
export declare type RouteDecorator = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE' | 'LIST';
export declare type RouteMethod = 'get' | 'post' | 'patch' | 'put' | 'delete';
export declare type RouteAction = 'create' | 'read' | 'update' | 'delete' | 'list';
export declare type Roles = string[];
export declare type RolesFn = (returns?: void) => Roles;
export interface DocumentAttribute {
[key: string]: AttributeObject;
}
export interface AttributeObject {
attribute: string;
roles?: AttributeRoles;
schema?: Schema;
metadata?: any;
}
export interface AttributeRoles {
readers: Roles;
writers: Roles;
}
export interface RoleAttributes {
read: string[];
write: string[];
}
export interface RoleObject {
[key: string]: RoleAttributes;
}
export declare type SchemaFn = (enjoi: (type?: any) => typeof Joi | any, joi?: any) => typeof Joi | boolean | Object;
export interface SchemaStructure {
[key: string]: Schema;
}
export declare type DecoratorId = 'Attribute' | 'Authorized' | 'Description' | 'Index' | 'Collection' | 'Document' | 'Nested' | 'Route' | 'Route.auth' | 'Route.roles' | RelationType | EventDecorator | 'Task' | 'Function';
export declare type DecoratorStorage = {
[key in DecoratorId]?: DecoratorObject[];
};
export interface DecoratorObject {
decorator: DecoratorId;
prototype: any;
attribute?: string;
[key: string]: any;
}
export declare type RelationType = 'OneToOne' | 'OneToMany';
export interface Relation<T = any> {
type: RelationType;
document: T;
attribute: string;
}
export interface RelationStructure<T> {
[key: string]: Relation<T>;
}
export interface JoiContainer {
schema: Schema;
opt: ValidationOptions;
}
export declare type AnyJoiSchema = AnySchema & ArraySchema & AlternativesSchema & BinarySchema & BooleanSchema & DateSchema & FunctionSchema & NumberSchema & ObjectSchema & StringSchema & LazySchema;
export declare type Enjoi = typeof enjoi;
export declare type ValidateSchema = Schema | JoiContainer;
export declare type ValidateSchemaFn = (returns: AnyJoiSchema, enjoi: Enjoi) => AnyJoiSchema;
export interface RouteBaseOpt {
deprecated?: boolean;
tags?: string[];
summary?: string;
description?: string;
}
export interface RouteOpt extends RouteBaseOpt {
action?: 'list';
body?: RouteBody;
pathParams?: RoutePathParam[];
queryParams?: RouteQueryParam[];
response?: Partial<RouteResponse>;
errors?: RouteError[];
path?: string;
process?: boolean;
handlerName?: string;
handler?: (arg: RouteArg) => any;
cache?: string | number;
roles?: Roles;
schema?: Schema | SchemaFn;
relations?: string[] | true;
}
interface TemplateStringsArray extends ReadonlyArray<string> {
readonly raw: ReadonlyArray<string>;
}
interface Aql {
(strings: TemplateStringsArray, ...args: any[]): ArangoDB.Query;
literal(value: any): ArangoDB.AqlLiteral;
}
declare type RouteArgFetch = (strings: TemplateStringsArray, ...args: any[]) => any[];
export interface RouteRolesArg {
$: (strings: TemplateStringsArray, ...args: any[]) => ArangoDB.Cursor;
_: RouteArgFetch;
_key: string;
action: RouteAction;
aql: Aql;
auth: RouteAuthorize;
collection: ArangoDB.Collection;
db: ArangoDB.Database;
document: (selector?: string | ArangoDB.DocumentLike) => DocumentData;
error: (status: ArangoDB.HttpStatus, reason?: string) => Foxx.Response;
exists: (selector: string) => boolean;
fetch: RouteArgFetch;
hasAuth: boolean;
insert: (data: DocumentData, options?: ArangoDB.InsertOptions) => ArangoDB.InsertResult;
method: RouteMethod;
name: string;
param: {
[key: string]: any;
};
path: string;
query: (query: ArangoDB.Query, options?: ArangoDB.QueryOptions) => ArangoDB.Cursor;
relations: (data: DocumentData) => DocumentData;
remove: (selector: string | ArangoDB.DocumentLike, options?: ArangoDB.RemoveOptions) => ArangoDB.RemoveResult;
replace: (selector: string | ArangoDB.DocumentLike, data: DocumentData, options?: ArangoDB.ReplaceOptions) => ArangoDB.UpdateResult;
req: Foxx.Request;
requestedAttributes: string[];
res: Foxx.Response;
roles?: Roles;
session: (set?: Partial<Foxx.Session>) => Foxx.Session;
update: (selector: string | ArangoDB.DocumentLike | DocumentData, data?: DocumentData, options?: ArangoDB.UpdateOptions) => ArangoDB.UpdateResult;
validParams: string[];
}
export declare type RouteRoles = (arg: RouteRolesArg) => Roles;
export declare type RouteAuth = (arg: RouteAuthArg) => boolean;
export interface RouteGroups {
creators: Roles;
readers: Roles;
updaters: Roles;
deleters: Roles;
}
export interface RouteArg extends RouteRolesArg, RouteBaseOpt {
userRoles: string[];
json: (omitUnwritableAttributes?: boolean) => DocumentData;
send: (data: DocumentData | any, omitUnreadableAttributes?: boolean) => Foxx.Response;
}
export declare type TypeFn = (returns?: void) => Class;
declare type RouteStatus = number | ArangoDB.HttpStatus;
export declare type RouteError = [RouteStatus, string];
export declare type RouteParam = [string, Schema, string?];
export declare type RouteQueryParam = RouteParam;
export declare type RoutePathParam = RouteParam;
export declare type RouteBody = [Schema, string?];
export declare type RouteHandler = (args: RouteArg) => any;
export interface RouteResponse {
status: RouteStatus;
schema: Foxx.Schema | Foxx.Model;
mime: string[];
description?: string;
}
export interface RouteAuthArg {
req: Foxx.Request;
res: Foxx.Response;
session: Foxx.Session;
method?: RouteMethod;
action?: RouteAction;
roles: Roles;
document: DocumentData;
doc: DocumentData;
}
export declare type RouteAuthorize = (doc: DocumentData, method?: RouteMethod, action?: RouteAction) => false | DocumentData;
export declare type DocumentForClient = (doc: DocumentData, opt: any) => DocumentData;
export declare type DocumentFromClient = (doc: DocumentData, opt: any) => DocumentData;
declare type QueryFilterLogicalOperator = '&&' | '||' | 'AND' | 'OR';
declare type QueryFilterComparisonOperator = '==' | '!=' | '<' | '<=' | '>' | '>=' | 'IN' | 'NOT IN' | 'LIKE' | '=~' | '!~' | 'HAS';
declare type QueryFilterValue = undefined | string | number | boolean | [QueryFilterComparisonOperator, ...(string | number | boolean)[]];
export interface QueryFilter {
$?: QueryFilterLogicalOperator;
[key: string]: QueryFilterValue;
}
export interface QueryOpt {
collection?: string;
filter?: QueryFilter | QueryFilter[];
sort?: string[];
limit?: number | [number, number];
keep?: string[];
unset?: string[];
aggregate?: string | boolean;
}
export declare type EventDecorator = 'After.document.class' | 'After.document.prop' | 'Before.document.class' | 'Before.document.prop' | 'After.insert.class' | 'After.insert.prop' | 'Before.insert.class' | 'Before.insert.prop' | 'After.update.class' | 'After.update.prop' | 'Before.update.class' | 'Before.update.prop' | 'After.replace.class' | 'After.replace.prop' | 'Before.replace.class' | 'Before.replace.prop' | 'After.modify.class' | 'After.modify.prop' | 'Before.modify.class' | 'Before.modify.prop' | 'After.write.class' | 'After.write.prop' | 'Before.write.class' | 'Before.write.prop' | 'After.remove.class' | 'After.remove.prop' | 'Before.remove.class' | 'Before.remove.prop';
export declare type EventType = 'After.document' | 'Before.document' | 'After.insert' | 'Before.insert' | 'After.update' | 'Before.update' | 'After.modify' | 'Before.modify' | 'After.write' | 'Before.write' | 'After.replace' | 'Before.replace' | 'After.remove' | 'Before.remove';
export declare type EventMethod = 'document' | 'insert' | 'update' | 'replace' | 'modify' | 'write' | 'remove';
export {};