axe-api 0.31.4 → 1.0.0-rc10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/dev-kit.d.ts +1 -0
- package/build/dev-kit.js +16 -0
- package/build/index.d.ts +3 -2
- package/build/index.js +6 -1
- package/build/src/Builders/ModelTreeBuilder.js +1 -2
- package/build/src/Builders/RouterBuilder.d.ts +1 -5
- package/build/src/Builders/RouterBuilder.js +17 -112
- package/build/src/Enums.d.ts +0 -7
- package/build/src/Enums.js +14 -22
- package/build/src/Handlers/DocsHTMLHandler.d.ts +3 -2
- package/build/src/Handlers/Helpers.d.ts +7 -7
- package/build/src/Handlers/MetadataHandler.d.ts +3 -2
- package/build/src/Handlers/RequestHandler.d.ts +3 -0
- package/build/src/Handlers/RequestHandler.js +99 -0
- package/build/src/Handlers/RoutesHandler.d.ts +3 -2
- package/build/src/Helpers.d.ts +1 -3
- package/build/src/Helpers.js +4 -68
- package/build/src/Interfaces.d.ts +74 -35
- package/build/src/Middlewares/RateLimit/AdaptorFactory.d.ts +6 -0
- package/build/src/Middlewares/RateLimit/AdaptorFactory.js +17 -0
- package/build/src/Middlewares/RateLimit/IAdaptor.d.ts +6 -0
- package/build/src/Middlewares/RateLimit/IAdaptor.js +2 -0
- package/build/src/Middlewares/RateLimit/MemoryAdaptor.d.ts +10 -0
- package/build/src/Middlewares/RateLimit/MemoryAdaptor.js +41 -0
- package/build/src/Middlewares/RateLimit/RedisAdaptor.d.ts +11 -0
- package/build/src/Middlewares/RateLimit/RedisAdaptor.js +35 -0
- package/build/src/Middlewares/RateLimit/index.d.ts +6 -0
- package/build/src/Middlewares/RateLimit/index.js +118 -0
- package/build/src/Model.d.ts +4 -4
- package/build/src/Phases/All/FetchPhase.d.ts +3 -0
- package/build/src/{Middlewares/acceptLanguageMiddleware.js → Phases/All/FetchPhase.js} +4 -10
- package/build/src/Phases/All/PreparePhase.d.ts +3 -0
- package/build/src/Phases/All/PreparePhase.js +30 -0
- package/build/src/Phases/All/index.d.ts +4 -0
- package/build/src/{Middlewares → Phases/All}/index.js +4 -3
- package/build/src/Phases/Delete/ActionPhase.d.ts +3 -0
- package/build/src/Phases/Delete/ActionPhase.js +24 -0
- package/build/src/Phases/Delete/PreparePhase.d.ts +3 -0
- package/build/src/Phases/Delete/PreparePhase.js +25 -0
- package/build/src/Phases/Delete/QueryPhase.d.ts +3 -0
- package/build/src/Phases/Delete/QueryPhase.js +22 -0
- package/build/src/Phases/Delete/ResponsePhase.d.ts +3 -0
- package/build/src/Phases/Delete/ResponsePhase.js +14 -0
- package/build/src/Phases/Delete/index.d.ts +7 -0
- package/build/src/Phases/Delete/index.js +15 -0
- package/build/src/Phases/ForceDelete/ActionPhase.d.ts +3 -0
- package/build/src/Phases/ForceDelete/ActionPhase.js +16 -0
- package/build/src/Phases/ForceDelete/PreparePhase.d.ts +3 -0
- package/build/src/Phases/ForceDelete/PreparePhase.js +30 -0
- package/build/src/Phases/ForceDelete/QueryPhase.d.ts +3 -0
- package/build/src/Phases/ForceDelete/QueryPhase.js +22 -0
- package/build/src/Phases/ForceDelete/index.d.ts +6 -0
- package/build/src/Phases/ForceDelete/index.js +13 -0
- package/build/src/Phases/List/RelationalPhase.d.ts +3 -0
- package/build/src/Phases/List/RelationalPhase.js +17 -0
- package/build/src/Phases/List/ResultPhase.d.ts +3 -0
- package/build/src/Phases/List/ResultPhase.js +14 -0
- package/build/src/Phases/List/SerializePhase.d.ts +3 -0
- package/build/src/Phases/List/SerializePhase.js +19 -0
- package/build/src/Phases/List/index.d.ts +6 -0
- package/build/src/Phases/List/index.js +13 -0
- package/build/src/Phases/Paginate/FetchPhase.d.ts +3 -0
- package/build/src/Phases/Paginate/FetchPhase.js +30 -0
- package/build/src/Phases/Paginate/PreparePhase.d.ts +3 -0
- package/build/src/Phases/Paginate/PreparePhase.js +22 -0
- package/build/src/Phases/Paginate/index.d.ts +5 -0
- package/build/src/Phases/Paginate/index.js +11 -0
- package/build/src/Phases/Patch/PrepareActionPhase.d.ts +3 -0
- package/build/src/Phases/Patch/PrepareActionPhase.js +37 -0
- package/build/src/Phases/Patch/index.d.ts +4 -0
- package/build/src/Phases/Patch/index.js +9 -0
- package/build/src/Phases/Show/FetchPhase.d.ts +3 -0
- package/build/src/Phases/Show/FetchPhase.js +35 -0
- package/build/src/Phases/Show/PreparePhase.d.ts +3 -0
- package/build/src/Phases/Show/PreparePhase.js +22 -0
- package/build/src/Phases/Show/index.d.ts +5 -0
- package/build/src/Phases/Show/index.js +11 -0
- package/build/src/Phases/Single/GetPhase.d.ts +3 -0
- package/build/src/Phases/Single/GetPhase.js +29 -0
- package/build/src/Phases/Single/PrepareGetPhase.d.ts +3 -0
- package/build/src/Phases/Single/PrepareGetPhase.js +19 -0
- package/build/src/Phases/Single/RelationalPhase.d.ts +3 -0
- package/build/src/Phases/Single/RelationalPhase.js +17 -0
- package/build/src/Phases/Single/ResultPhase.d.ts +3 -0
- package/build/src/Phases/Single/ResultPhase.js +14 -0
- package/build/src/Phases/Single/SerializePhase.d.ts +3 -0
- package/build/src/Phases/Single/SerializePhase.js +18 -0
- package/build/src/Phases/Single/index.d.ts +8 -0
- package/build/src/Phases/Single/index.js +17 -0
- package/build/src/Phases/Store/ActionPhase.d.ts +3 -0
- package/build/src/Phases/Store/ActionPhase.js +29 -0
- package/build/src/Phases/Store/PreparePhase.d.ts +3 -0
- package/build/src/Phases/Store/PreparePhase.js +46 -0
- package/build/src/Phases/Store/index.d.ts +5 -0
- package/build/src/Phases/Store/index.js +11 -0
- package/build/src/Phases/Update/ActionPhase.d.ts +3 -0
- package/build/src/Phases/Update/ActionPhase.js +22 -0
- package/build/src/Phases/Update/PrepareActionPhase.d.ts +3 -0
- package/build/src/Phases/Update/PrepareActionPhase.js +37 -0
- package/build/src/Phases/Update/index.d.ts +5 -0
- package/build/src/Phases/Update/index.js +11 -0
- package/build/src/Resolvers/ModelResolver.js +9 -4
- package/build/src/Resolvers/VersionConfigResolver.js +6 -1
- package/build/src/Resolvers/VersionResolver.js +1 -2
- package/build/src/Server.d.ts +0 -1
- package/build/src/Server.js +29 -24
- package/build/src/Services/APIService.d.ts +3 -3
- package/build/src/Services/APIService.js +3 -8
- package/build/src/Services/App.d.ts +14 -0
- package/build/src/Services/App.js +80 -0
- package/build/src/Services/AxeRequest.d.ts +26 -0
- package/build/src/Services/AxeRequest.js +85 -0
- package/build/src/Services/AxeResponse.d.ts +18 -0
- package/build/src/Services/AxeResponse.js +41 -0
- package/build/src/Services/ConverterService.d.ts +9 -0
- package/build/src/Services/ConverterService.js +49 -0
- package/build/src/Services/LogService.d.ts +8 -12
- package/build/src/Services/LogService.js +16 -34
- package/build/src/Services/ModelService.d.ts +4 -4
- package/build/src/Services/QueryService.d.ts +4 -4
- package/build/src/Services/QueryService.js +14 -11
- package/build/src/Services/SchemaValidatorService.js +1 -2
- package/build/src/Services/URLService.d.ts +29 -0
- package/build/src/Services/URLService.js +144 -0
- package/build/src/Services/index.d.ts +4 -1
- package/build/src/Services/index.js +7 -1
- package/build/src/Types.d.ts +18 -6
- package/build/src/constants.d.ts +12 -14
- package/build/src/constants.js +200 -13
- package/package.json +29 -20
- package/build/src/Handlers/AllHandler.d.ts +0 -3
- package/build/src/Handlers/AllHandler.js +0 -45
- package/build/src/Handlers/DestroyHandler.d.ts +0 -3
- package/build/src/Handlers/DestroyHandler.js +0 -51
- package/build/src/Handlers/ForceDestroyHandler.d.ts +0 -3
- package/build/src/Handlers/ForceDestroyHandler.js +0 -45
- package/build/src/Handlers/HandlerFactory.d.ts +0 -6
- package/build/src/Handlers/HandlerFactory.js +0 -39
- package/build/src/Handlers/PaginateHandler.d.ts +0 -3
- package/build/src/Handlers/PaginateHandler.js +0 -49
- package/build/src/Handlers/PatchHandler.d.ts +0 -3
- package/build/src/Handlers/PatchHandler.js +0 -69
- package/build/src/Handlers/ShowHandler.d.ts +0 -3
- package/build/src/Handlers/ShowHandler.js +0 -55
- package/build/src/Handlers/StoreHandler.d.ts +0 -3
- package/build/src/Handlers/StoreHandler.js +0 -65
- package/build/src/Handlers/UpdateHandler.d.ts +0 -3
- package/build/src/Handlers/UpdateHandler.js +0 -69
- package/build/src/Middlewares/acceptLanguageMiddleware.d.ts +0 -3
- package/build/src/Middlewares/index.d.ts +0 -2
|
@@ -1,10 +1,17 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="express" />
|
|
1
3
|
import { Knex } from "knex";
|
|
2
|
-
import {
|
|
4
|
+
import { Options as FormOptions } from "formidable";
|
|
3
5
|
import { Column } from "knex-schema-inspector/lib/types/column";
|
|
4
|
-
import { HandlerTypes,
|
|
6
|
+
import { HandlerTypes, HttpMethods, HookFunctionTypes, Extensions, Relationships, SortTypes, ConditionTypes, DependencyTypes, QueryFeature, QueryFeatureType } from "./Enums";
|
|
5
7
|
import Model from "./Model";
|
|
6
|
-
import {
|
|
7
|
-
import { ModelListService } from "./Services";
|
|
8
|
+
import { AdaptorTypes, HandlerFunction, HookFunctions, MiddlewareFunction, StepTypes, PhaseFunction, SerializationFunction } from "./Types";
|
|
9
|
+
import { ModelListService, QueryService } from "./Services";
|
|
10
|
+
import AxeRequest from "./Services/AxeRequest";
|
|
11
|
+
import AxeResponse from "./Services/AxeResponse";
|
|
12
|
+
import App from "./Services/App";
|
|
13
|
+
import { LoggerOptions } from "pino";
|
|
14
|
+
import { IncomingMessage } from "http";
|
|
8
15
|
export interface IColumn extends Column {
|
|
9
16
|
table_name: string;
|
|
10
17
|
}
|
|
@@ -16,7 +23,7 @@ export interface IHandlerBasedTransactionConfig {
|
|
|
16
23
|
}
|
|
17
24
|
interface IHandlerBasedSerializer {
|
|
18
25
|
handler: HandlerTypes[];
|
|
19
|
-
serializer: ((data: any, request:
|
|
26
|
+
serializer: ((data: any, request: AxeRequest) => void)[];
|
|
20
27
|
}
|
|
21
28
|
export interface IQueryLimitConfig {
|
|
22
29
|
feature: QueryFeature;
|
|
@@ -32,20 +39,44 @@ export interface IQueryConfig {
|
|
|
32
39
|
limits: Array<IQueryLimitConfig[]>;
|
|
33
40
|
defaults?: IQueryDefaultConfig;
|
|
34
41
|
}
|
|
35
|
-
export interface
|
|
42
|
+
export interface IRedisOptions {
|
|
43
|
+
host?: string;
|
|
44
|
+
port?: number;
|
|
45
|
+
password?: string;
|
|
46
|
+
db?: number;
|
|
47
|
+
}
|
|
48
|
+
export interface IRateLimitAdaptorConfig {
|
|
49
|
+
type: AdaptorTypes;
|
|
50
|
+
redis?: IRedisOptions;
|
|
51
|
+
}
|
|
52
|
+
export interface IRateLimitOptions {
|
|
53
|
+
maxRequests: number;
|
|
54
|
+
windowInSeconds: number;
|
|
55
|
+
}
|
|
56
|
+
export interface IRateLimitConfig extends IRateLimitOptions {
|
|
57
|
+
enabled: boolean;
|
|
58
|
+
adaptor: IRateLimitAdaptorConfig;
|
|
59
|
+
trustProxyIP: boolean;
|
|
60
|
+
keyGenerator?: (req: IncomingMessage) => string;
|
|
61
|
+
}
|
|
62
|
+
export interface AxeVersionConfig {
|
|
36
63
|
transaction: boolean | IHandlerBasedTransactionConfig | IHandlerBasedTransactionConfig[];
|
|
37
|
-
serializers: ((data: any, request:
|
|
64
|
+
serializers: ((data: any, request: AxeRequest) => void)[] | IHandlerBasedSerializer[];
|
|
38
65
|
supportedLanguages: string[];
|
|
39
66
|
defaultLanguage: string;
|
|
40
67
|
query: IQueryConfig;
|
|
68
|
+
formidable: FormOptions;
|
|
41
69
|
}
|
|
42
|
-
export
|
|
70
|
+
export type IVersionConfig = Partial<AxeVersionConfig>;
|
|
71
|
+
export interface AxeConfig extends IConfig {
|
|
43
72
|
env: string;
|
|
44
73
|
port: number;
|
|
45
|
-
logLevel: LogLevels;
|
|
46
74
|
prefix: string;
|
|
47
75
|
database: IDatabaseConfig;
|
|
76
|
+
pino: LoggerOptions;
|
|
77
|
+
rateLimit: IRateLimitConfig;
|
|
48
78
|
}
|
|
79
|
+
export type IApplicationConfig = Partial<AxeConfig>;
|
|
49
80
|
export interface ILanguage {
|
|
50
81
|
title: string;
|
|
51
82
|
language: string;
|
|
@@ -67,7 +98,7 @@ export interface IVersionFolder {
|
|
|
67
98
|
}
|
|
68
99
|
export interface IVersion {
|
|
69
100
|
name: string;
|
|
70
|
-
config:
|
|
101
|
+
config: AxeVersionConfig;
|
|
71
102
|
folders: IVersionFolder;
|
|
72
103
|
modelList: ModelListService;
|
|
73
104
|
modelTree: IModelService[];
|
|
@@ -76,29 +107,15 @@ export interface IAPI {
|
|
|
76
107
|
rootFolder: string;
|
|
77
108
|
appFolder: string;
|
|
78
109
|
versions: IVersion[];
|
|
79
|
-
config:
|
|
110
|
+
config: AxeConfig;
|
|
80
111
|
}
|
|
81
112
|
export interface IGeneralHooks {
|
|
82
|
-
onBeforeInit: (app:
|
|
83
|
-
onAfterInit: (app:
|
|
113
|
+
onBeforeInit: (app: App) => void | null;
|
|
114
|
+
onAfterInit: (app: App) => void | null;
|
|
84
115
|
}
|
|
85
116
|
export interface IHandlerBaseMiddleware {
|
|
86
117
|
handler: HandlerTypes[];
|
|
87
|
-
middleware:
|
|
88
|
-
}
|
|
89
|
-
export interface IHookParameter {
|
|
90
|
-
req: Request;
|
|
91
|
-
res: Response;
|
|
92
|
-
handlerType: HandlerTypes;
|
|
93
|
-
model: IModelService;
|
|
94
|
-
parentModel: IModelService | null;
|
|
95
|
-
relation: IRelation | null;
|
|
96
|
-
database: Knex | Knex.Transaction;
|
|
97
|
-
conditions: IQuery | null;
|
|
98
|
-
query: Knex.QueryBuilder | null;
|
|
99
|
-
result: any;
|
|
100
|
-
item: any;
|
|
101
|
-
formData: any;
|
|
118
|
+
middleware: StepTypes;
|
|
102
119
|
}
|
|
103
120
|
export interface IMethodBaseConfig {
|
|
104
121
|
[HttpMethods.POST]?: string[];
|
|
@@ -115,14 +132,14 @@ export interface IModelService {
|
|
|
115
132
|
relations: IRelation[];
|
|
116
133
|
columns: IColumn[];
|
|
117
134
|
columnNames: string[];
|
|
118
|
-
hooks:
|
|
119
|
-
events:
|
|
135
|
+
hooks: HookFunctions;
|
|
136
|
+
events: HookFunctions;
|
|
120
137
|
isRecursive: boolean;
|
|
121
138
|
children: IModelService[];
|
|
122
139
|
queryLimits: IQueryLimitConfig[];
|
|
123
140
|
serialize: SerializationFunction | null;
|
|
124
141
|
setColumns(columns: IColumn[]): void;
|
|
125
|
-
setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data:
|
|
142
|
+
setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data: PhaseFunction): void;
|
|
126
143
|
setQueryLimits(limits: IQueryLimitConfig[]): void;
|
|
127
144
|
setSerialization(callback: SerializationFunction): void;
|
|
128
145
|
}
|
|
@@ -133,16 +150,25 @@ export interface IRelation {
|
|
|
133
150
|
primaryKey: string;
|
|
134
151
|
foreignKey: string;
|
|
135
152
|
}
|
|
136
|
-
export interface
|
|
137
|
-
api: IAPI;
|
|
153
|
+
export interface IRouteData {
|
|
138
154
|
version: IVersion;
|
|
139
|
-
req: Request;
|
|
140
|
-
res: Response;
|
|
141
155
|
handlerType: HandlerTypes;
|
|
142
156
|
model: IModelService;
|
|
143
157
|
parentModel: IModelService | null;
|
|
144
158
|
relation: IRelation | null;
|
|
159
|
+
}
|
|
160
|
+
export interface IRequestPack extends IRouteData {
|
|
161
|
+
api: IAPI;
|
|
162
|
+
req: AxeRequest;
|
|
163
|
+
res: AxeResponse;
|
|
145
164
|
database: Knex | Knex.Transaction;
|
|
165
|
+
queryParser?: QueryService;
|
|
166
|
+
conditions?: IQuery;
|
|
167
|
+
query?: Knex.QueryBuilder;
|
|
168
|
+
params?: any;
|
|
169
|
+
result?: any;
|
|
170
|
+
item?: any;
|
|
171
|
+
formData?: any;
|
|
146
172
|
}
|
|
147
173
|
export interface IRouteDocumentation {
|
|
148
174
|
version: string;
|
|
@@ -202,4 +228,17 @@ export interface IDependency {
|
|
|
202
228
|
callback: any;
|
|
203
229
|
instance: any;
|
|
204
230
|
}
|
|
231
|
+
export interface IPhaseDefinition {
|
|
232
|
+
name: string;
|
|
233
|
+
isAsync: boolean;
|
|
234
|
+
callback: PhaseFunction;
|
|
235
|
+
}
|
|
236
|
+
export interface AxeRequestResponsePair {
|
|
237
|
+
axeRequest: AxeRequest;
|
|
238
|
+
axeResponse: AxeResponse;
|
|
239
|
+
}
|
|
240
|
+
export interface MiddlewareResolution {
|
|
241
|
+
middlewares: (MiddlewareFunction | HandlerFunction)[];
|
|
242
|
+
handler: HandlerFunction;
|
|
243
|
+
}
|
|
205
244
|
export {};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { AdaptorTypes } from "../../Types";
|
|
2
|
+
import RedisAdaptor from "./RedisAdaptor";
|
|
3
|
+
import MemoryAdaptor from "./MemoryAdaptor";
|
|
4
|
+
import { IRedisOptions } from "src/Interfaces";
|
|
5
|
+
declare const _default: (adaptor: AdaptorTypes, redisOptions: IRedisOptions | undefined, prefix: string) => RedisAdaptor | MemoryAdaptor;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const RedisAdaptor_1 = __importDefault(require("./RedisAdaptor"));
|
|
7
|
+
const MemoryAdaptor_1 = __importDefault(require("./MemoryAdaptor"));
|
|
8
|
+
exports.default = (adaptor, redisOptions, prefix) => {
|
|
9
|
+
switch (adaptor) {
|
|
10
|
+
case "redis":
|
|
11
|
+
return new RedisAdaptor_1.default(redisOptions, prefix);
|
|
12
|
+
case "memory":
|
|
13
|
+
return new MemoryAdaptor_1.default(prefix);
|
|
14
|
+
default:
|
|
15
|
+
throw new Error(`Adaptor type is not found: ${adaptor}`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import IAdaptor from "./IAdaptor";
|
|
2
|
+
declare class MemoryAdaptor implements IAdaptor {
|
|
3
|
+
private client;
|
|
4
|
+
private prefix;
|
|
5
|
+
constructor(prefix: string);
|
|
6
|
+
get(key: string): Promise<string | null>;
|
|
7
|
+
set(key: string, value: string, ttl: number): Promise<void>;
|
|
8
|
+
decr(key: string, ttl: number): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
export default MemoryAdaptor;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const node_cache_1 = __importDefault(require("node-cache"));
|
|
16
|
+
class MemoryAdaptor {
|
|
17
|
+
constructor(prefix) {
|
|
18
|
+
this.client = new node_cache_1.default();
|
|
19
|
+
this.prefix = prefix;
|
|
20
|
+
}
|
|
21
|
+
get(key) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
return this.client.get(`${this.prefix}${key}`) || null;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
set(key, value, ttl) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
this.client.set(`${this.prefix}${key}`, value, ttl);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
decr(key, ttl) {
|
|
32
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
33
|
+
const value = yield this.get(key);
|
|
34
|
+
if (value) {
|
|
35
|
+
const newValue = parseInt(value) - 1;
|
|
36
|
+
this.set(key, newValue.toString(), ttl);
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.default = MemoryAdaptor;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import IAdaptor from "./IAdaptor";
|
|
2
|
+
import { IRedisOptions } from "../../Interfaces";
|
|
3
|
+
declare class RedisAdaptor implements IAdaptor {
|
|
4
|
+
private client;
|
|
5
|
+
private prefix;
|
|
6
|
+
constructor(options: IRedisOptions | undefined, prefix: string);
|
|
7
|
+
get(key: string): Promise<string | null>;
|
|
8
|
+
set(key: string, value: string, ttl: number): Promise<void>;
|
|
9
|
+
decr(key: string): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
export default RedisAdaptor;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const redis_1 = require("redis");
|
|
13
|
+
class RedisAdaptor {
|
|
14
|
+
constructor(options, prefix) {
|
|
15
|
+
this.client = (0, redis_1.createClient)(options);
|
|
16
|
+
this.prefix = prefix;
|
|
17
|
+
this.client.connect();
|
|
18
|
+
}
|
|
19
|
+
get(key) {
|
|
20
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
+
return yield this.client.get(`${this.prefix}${key}`);
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
set(key, value, ttl) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
yield this.client.setEx(`${this.prefix}${key}`, ttl, value);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
decr(key) {
|
|
30
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
31
|
+
yield this.client.decr(`${this.prefix}${key}`);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.default = RedisAdaptor;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse } from "http";
|
|
2
|
+
import { AxeConfig, IRateLimitOptions, IRequestPack } from "../../Interfaces";
|
|
3
|
+
export declare const setupRateLimitAdaptors: (config: AxeConfig) => void;
|
|
4
|
+
export declare const rateLimit: (options?: IRateLimitOptions) => (context: IRequestPack) => Promise<void>;
|
|
5
|
+
declare const _default: (req: IncomingMessage, res: ServerResponse, next: any) => Promise<any>;
|
|
6
|
+
export default _default;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.rateLimit = exports.setupRateLimitAdaptors = void 0;
|
|
16
|
+
const AdaptorFactory_1 = __importDefault(require("./AdaptorFactory"));
|
|
17
|
+
const Services_1 = require("../../Services");
|
|
18
|
+
const nanoid_1 = require("nanoid");
|
|
19
|
+
let adaptor;
|
|
20
|
+
const checkRateLimit = function (clientKey, options) {
|
|
21
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
22
|
+
// Getting the last value from cache
|
|
23
|
+
const reply = yield adaptor.get(clientKey);
|
|
24
|
+
if (!reply) {
|
|
25
|
+
// First request from this IP, set initial values
|
|
26
|
+
yield adaptor.set(clientKey, (options.maxRequests - 1).toString(), options.windowInSeconds);
|
|
27
|
+
return {
|
|
28
|
+
success: true,
|
|
29
|
+
limit: options.maxRequests,
|
|
30
|
+
remaining: options.maxRequests - 1,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// Is there any remaining request right
|
|
34
|
+
const remainingRequests = parseInt(reply);
|
|
35
|
+
if (remainingRequests > 0) {
|
|
36
|
+
// Set the new value to the cache
|
|
37
|
+
yield adaptor.decr(clientKey, options.windowInSeconds);
|
|
38
|
+
return {
|
|
39
|
+
success: true,
|
|
40
|
+
limit: options.maxRequests,
|
|
41
|
+
remaining: remainingRequests - 1,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// Client has exceeded rate limit
|
|
45
|
+
return {
|
|
46
|
+
success: false,
|
|
47
|
+
limit: options.maxRequests,
|
|
48
|
+
remaining: 0,
|
|
49
|
+
};
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const getClientKeyByConfigurations = (req, config) => {
|
|
53
|
+
if (config === null || config === void 0 ? void 0 : config.keyGenerator) {
|
|
54
|
+
return config === null || config === void 0 ? void 0 : config.keyGenerator(req);
|
|
55
|
+
}
|
|
56
|
+
if (config === null || config === void 0 ? void 0 : config.trustProxyIP) {
|
|
57
|
+
// Getting the x-forwarded-for value for the Proxy servers.
|
|
58
|
+
let headerValue = req.headers["x-forwarded-for"];
|
|
59
|
+
if (Array.isArray(headerValue)) {
|
|
60
|
+
headerValue = headerValue[0];
|
|
61
|
+
}
|
|
62
|
+
return `axe-api-rate-limit:${headerValue || ""}`;
|
|
63
|
+
}
|
|
64
|
+
return `axe-api-rate-limit:${req.socket.remoteAddress || ""}`;
|
|
65
|
+
};
|
|
66
|
+
const setupRateLimitAdaptors = (config) => {
|
|
67
|
+
var _a, _b;
|
|
68
|
+
// Creating the correct adaptor by the configuration
|
|
69
|
+
adaptor = (0, AdaptorFactory_1.default)(((_a = config.rateLimit) === null || _a === void 0 ? void 0 : _a.adaptor.type) || "memory", (_b = config.rateLimit) === null || _b === void 0 ? void 0 : _b.adaptor.redis, "");
|
|
70
|
+
};
|
|
71
|
+
exports.setupRateLimitAdaptors = setupRateLimitAdaptors;
|
|
72
|
+
const rateLimit = (options) => {
|
|
73
|
+
// For each model middleware, we should use a different ID for the cache key
|
|
74
|
+
const id = (0, nanoid_1.nanoid)();
|
|
75
|
+
return (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
76
|
+
// API configuration fetching
|
|
77
|
+
const api = Services_1.APIService.getInstance();
|
|
78
|
+
// Creating a clientkey by the client key configurations
|
|
79
|
+
const clientKey = getClientKeyByConfigurations(context.req.original, api.config.rateLimit);
|
|
80
|
+
// Developers are able to set different rate limit options
|
|
81
|
+
// in model files. That's why we should create a new option object.
|
|
82
|
+
const selectedOptions = Object.assign(Object.assign({}, api.config.rateLimit), options);
|
|
83
|
+
// Checking the rate limit
|
|
84
|
+
const isAllowed = yield checkRateLimit(`${clientKey}:${id}`, selectedOptions);
|
|
85
|
+
// Setting the headers
|
|
86
|
+
context.res.original.setHeader("X-RateLimit-Limit", isAllowed.limit);
|
|
87
|
+
context.res.original.setHeader("X-RateLimit-Remaining", isAllowed.remaining);
|
|
88
|
+
// Sending an error message if there is an error
|
|
89
|
+
if (isAllowed.success === false) {
|
|
90
|
+
Services_1.LogService.warn(`Rate limit exceeded: ${context.req.url}`);
|
|
91
|
+
context.res.status(429).json({ error: "Rate limit exceeded." });
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
exports.rateLimit = rateLimit;
|
|
96
|
+
exports.default = (req, res, next) => __awaiter(void 0, void 0, void 0, function* () {
|
|
97
|
+
const api = Services_1.APIService.getInstance();
|
|
98
|
+
// Generating the client key
|
|
99
|
+
const clientKey = getClientKeyByConfigurations(req, api.config.rateLimit);
|
|
100
|
+
// Checking the rate limits.
|
|
101
|
+
const isAllowed = yield checkRateLimit(clientKey, {
|
|
102
|
+
maxRequests: api.config.rateLimit.maxRequests,
|
|
103
|
+
windowInSeconds: api.config.rateLimit.windowInSeconds,
|
|
104
|
+
});
|
|
105
|
+
// Setting the HTTP Response headers.
|
|
106
|
+
res.setHeader("X-RateLimit-Limit", isAllowed.limit);
|
|
107
|
+
res.setHeader("X-RateLimit-Remaining", isAllowed.remaining);
|
|
108
|
+
// If it is allowed, the next function would be called.
|
|
109
|
+
if (isAllowed.success) {
|
|
110
|
+
return next();
|
|
111
|
+
}
|
|
112
|
+
// Sending an error message.
|
|
113
|
+
Services_1.LogService.warn(`Rate limit exceeded: ${req.url}`);
|
|
114
|
+
res.writeHead(429, { "Content-Type": "application/json" });
|
|
115
|
+
res.end(JSON.stringify({
|
|
116
|
+
error: "Rate limit exceeded.",
|
|
117
|
+
}));
|
|
118
|
+
});
|
package/build/src/Model.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { IRelation, IMethodBaseConfig, IMethodBaseValidations,
|
|
1
|
+
import { IRelation, IMethodBaseConfig, IMethodBaseValidations, IHandlerBasedTransactionConfig, IQueryLimitConfig } from "./Interfaces";
|
|
2
2
|
import { HandlerTypes, HttpMethods } from "./Enums";
|
|
3
|
-
import { FieldList,
|
|
3
|
+
import { FieldList, ModelMiddlewareDefinition, StepTypes, ModelValidation } from "./Types";
|
|
4
4
|
declare class Model {
|
|
5
5
|
get primaryKey(): string;
|
|
6
6
|
get table(): string;
|
|
7
7
|
get fillable(): FieldList | IMethodBaseConfig;
|
|
8
8
|
get validations(): IMethodBaseValidations | ModelValidation;
|
|
9
9
|
get handlers(): HandlerTypes[];
|
|
10
|
-
get middlewares():
|
|
10
|
+
get middlewares(): ModelMiddlewareDefinition;
|
|
11
11
|
get hiddens(): FieldList;
|
|
12
12
|
get createdAtColumn(): string | null;
|
|
13
13
|
get updatedAtColumn(): string | null;
|
|
@@ -17,7 +17,7 @@ declare class Model {
|
|
|
17
17
|
get limits(): Array<IQueryLimitConfig[]>;
|
|
18
18
|
getFillableFields(methodType: HttpMethods): string[];
|
|
19
19
|
getValidationRules(methodType: HttpMethods): ModelValidation | null;
|
|
20
|
-
getMiddlewares(handlerType: HandlerTypes):
|
|
20
|
+
getMiddlewares(handlerType: HandlerTypes): StepTypes[];
|
|
21
21
|
hasMany(relatedModel: string, primaryKey?: string, foreignKey?: string): IRelation;
|
|
22
22
|
hasOne(relatedModel: string, primaryKey?: string, foreignKey?: string): IRelation;
|
|
23
23
|
belongsTo(relatedModel: string, primaryKey: string, foreignKey: string): IRelation;
|
|
@@ -9,14 +9,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const version = yield (0, Helpers_1.getVersionByRequest)(req);
|
|
17
|
-
// Setting the current language by the supported, default and the client prefences
|
|
18
|
-
req.currentLanguage = Resolvers_1.AcceptLanguageResolver.resolve(req.get("accept-language") || "", version.config.supportedLanguages || ["en"], version.config.defaultLanguage || "en");
|
|
19
|
-
// Adding the `Content-Language` header to the response object
|
|
20
|
-
res.setHeader("Content-Language", req.currentLanguage.title);
|
|
21
|
-
next();
|
|
12
|
+
exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
if (context.query) {
|
|
14
|
+
context.result = yield context.query;
|
|
15
|
+
}
|
|
22
16
|
});
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const Services_1 = require("../../Services");
|
|
13
|
+
const Helpers_1 = require("../../Handlers/Helpers");
|
|
14
|
+
exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
15
|
+
context.queryParser = new Services_1.QueryService(context.model, context.version.modelList.get(), context.version.config);
|
|
16
|
+
// We should parse URL query string to use as condition in Lucid query
|
|
17
|
+
context.conditions = context.queryParser.get(context.req.query);
|
|
18
|
+
// Creating a new database query
|
|
19
|
+
context.query = context.database.from(context.model.instance.table);
|
|
20
|
+
// If there is a deletedAtColumn, it means that this table support soft-delete
|
|
21
|
+
(0, Helpers_1.addSoftDeleteQuery)(context.model, context.conditions, context.query);
|
|
22
|
+
// Users should be able to select some fields to show.
|
|
23
|
+
context.queryParser.applyFields(context.query, context.conditions.fields);
|
|
24
|
+
// Binding parent id if there is.
|
|
25
|
+
(0, Helpers_1.addForeignKeyQuery)(context.req, context.query, context.relation, context.parentModel);
|
|
26
|
+
// Users should be able to filter records
|
|
27
|
+
context.queryParser.applyWheres(context.query, context.conditions.q);
|
|
28
|
+
// User should be able to select sorting fields and types
|
|
29
|
+
context.queryParser.applySorting(context.query, context.conditions.sort);
|
|
30
|
+
});
|
|
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const FetchPhase_1 = __importDefault(require("./FetchPhase"));
|
|
7
|
+
exports.default = {
|
|
8
|
+
FetchPhase: FetchPhase_1.default,
|
|
9
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
13
|
+
if (context.query) {
|
|
14
|
+
// If there is a deletedAtColumn, it means that this table support soft-delete
|
|
15
|
+
if (context.model.instance.deletedAtColumn) {
|
|
16
|
+
yield context.query.update({
|
|
17
|
+
[context.model.instance.deletedAtColumn]: new Date(),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
yield context.query.delete();
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const Helpers_1 = require("../../Handlers/Helpers");
|
|
13
|
+
exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
+
// We should check the parameter type
|
|
15
|
+
const value = context.req.params[context.model.instance.primaryKey];
|
|
16
|
+
(0, Helpers_1.checkPrimaryKeyValueType)(context.model, value);
|
|
17
|
+
// Adding the main query
|
|
18
|
+
context.query = context.database
|
|
19
|
+
.from(context.model.instance.table)
|
|
20
|
+
.where(context.model.instance.primaryKey, value);
|
|
21
|
+
// If there is a deletedAtColumn, it means that this table support soft-delete
|
|
22
|
+
(0, Helpers_1.addSoftDeleteQuery)(context.model, null, context.query);
|
|
23
|
+
// If there is a relation, we should bind it
|
|
24
|
+
(0, Helpers_1.addForeignKeyQuery)(context.req, context.query, context.relation, context.parentModel);
|
|
25
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const Enums_1 = require("../../Enums");
|
|
13
|
+
exports.default = (context) => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
+
if (context.query) {
|
|
15
|
+
context.item = yield context.query.first();
|
|
16
|
+
if (!context.item) {
|
|
17
|
+
context.res
|
|
18
|
+
.status(Enums_1.StatusCodes.NOT_FOUND)
|
|
19
|
+
.json({ error: `The item is not found on ${context.model.name}.` });
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
});
|