axe-api 0.22.0 → 0.30.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 -3
- package/build/index.js +4 -1
- package/build/src/Builders/ModelTreeBuilder.d.ts +3 -0
- package/build/src/Builders/ModelTreeBuilder.js +21 -17
- package/build/src/Builders/RouterBuilder.d.ts +3 -0
- package/build/src/Builders/RouterBuilder.js +28 -27
- package/build/src/Enums.d.ts +98 -0
- package/build/src/Enums.js +103 -1
- package/build/src/Exceptions/ApiError.d.ts +1 -1
- package/build/src/Exceptions/ApiError.js +2 -2
- package/build/src/Exceptions/AxeError.d.ts +8 -0
- package/build/src/Exceptions/AxeError.js +11 -0
- package/build/src/Handlers/AllHandler.js +4 -5
- package/build/src/Handlers/DocsHandler.d.ts +3 -0
- package/build/src/Handlers/DocsHandler.js +22 -0
- package/build/src/Handlers/HandlerFactory.d.ts +1 -1
- package/build/src/Handlers/HandlerFactory.js +1 -1
- package/build/src/Handlers/Helpers.d.ts +5 -3
- package/build/src/Handlers/Helpers.js +29 -13
- package/build/src/Handlers/PaginateHandler.js +4 -5
- package/build/src/Handlers/PatchHandler.js +2 -2
- package/build/src/Handlers/RoutesHandler.d.ts +3 -0
- package/build/src/Handlers/RoutesHandler.js +16 -0
- package/build/src/Handlers/ShowHandler.js +4 -5
- package/build/src/Handlers/StoreHandler.js +2 -2
- package/build/src/Handlers/UpdateHandler.js +2 -2
- package/build/src/Helpers.d.ts +4 -0
- package/build/src/Helpers.js +78 -0
- package/build/src/Interfaces.d.ts +54 -14
- package/build/src/Middlewares/acceptLanguageMiddleware.js +3 -5
- package/build/src/Model.d.ts +2 -2
- package/build/src/Model.js +3 -4
- package/build/src/Resolvers/FileResolver.js +2 -2
- package/build/src/Resolvers/GeneralHookResolver.d.ts +4 -2
- package/build/src/Resolvers/GeneralHookResolver.js +5 -8
- package/build/src/Resolvers/ModelResolver.d.ts +7 -0
- package/build/src/Resolvers/ModelResolver.js +99 -19
- package/build/src/Resolvers/TransactionResolver.d.ts +4 -2
- package/build/src/Resolvers/TransactionResolver.js +5 -4
- package/build/src/Resolvers/VersionConfigResolver.d.ts +7 -0
- package/build/src/Resolvers/VersionConfigResolver.js +58 -0
- package/build/src/Resolvers/VersionResolver.d.ts +7 -0
- package/build/src/Resolvers/VersionResolver.js +65 -0
- package/build/src/Resolvers/index.d.ts +3 -2
- package/build/src/Resolvers/index.js +5 -3
- package/build/src/Server.d.ts +3 -2
- package/build/src/Server.js +73 -46
- package/build/src/Services/APIService.d.ts +16 -0
- package/build/src/Services/APIService.js +82 -0
- package/build/src/Services/DocumentationService.d.ts +3 -1
- package/build/src/Services/DocumentationService.js +6 -0
- package/build/src/Services/LimitService.d.ts +5 -0
- package/build/src/Services/LimitService.js +116 -0
- package/build/src/Services/LogService.d.ts +4 -1
- package/build/src/Services/LogService.js +6 -0
- package/build/src/Services/ModelService.d.ts +6 -1
- package/build/src/Services/ModelService.js +8 -0
- package/build/src/Services/QueryService.d.ts +3 -2
- package/build/src/Services/QueryService.js +32 -7
- package/build/src/Services/SchemaValidatorService.d.ts +7 -0
- package/build/src/Services/SchemaValidatorService.js +62 -8
- package/build/src/Services/index.d.ts +3 -1
- package/build/src/Services/index.js +6 -1
- package/build/src/Types.d.ts +2 -0
- package/build/src/Types.js +2 -0
- package/build/src/constants.d.ts +5 -1
- package/build/src/constants.js +43 -2
- package/package.json +26 -24
- package/CHANGELOG.md +0 -212
- package/build/src/Resolvers/FolderResolver.d.ts +0 -5
- package/build/src/Resolvers/FolderResolver.js +0 -19
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { IModelService, IRouteDocumentation } from "../Interfaces";
|
|
2
2
|
import { HttpMethods } from "../Enums";
|
|
3
3
|
declare class DocumentationService {
|
|
4
|
-
|
|
4
|
+
private static instance;
|
|
5
|
+
private routes;
|
|
5
6
|
constructor();
|
|
7
|
+
static getInstance(): DocumentationService;
|
|
6
8
|
push(method: HttpMethods, url: string, model: IModelService): void;
|
|
7
9
|
get(): IRouteDocumentation[];
|
|
8
10
|
}
|
|
@@ -4,6 +4,12 @@ class DocumentationService {
|
|
|
4
4
|
constructor() {
|
|
5
5
|
this.routes = [];
|
|
6
6
|
}
|
|
7
|
+
static getInstance() {
|
|
8
|
+
if (!DocumentationService.instance) {
|
|
9
|
+
DocumentationService.instance = new DocumentationService();
|
|
10
|
+
}
|
|
11
|
+
return DocumentationService.instance;
|
|
12
|
+
}
|
|
7
13
|
push(method, url, model) {
|
|
8
14
|
this.routes.push({
|
|
9
15
|
model: model.name,
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { QueryFeature } from "../Enums";
|
|
2
|
+
import { IModelService, IQueryLimitConfig } from "../Interfaces";
|
|
3
|
+
export declare const allow: (feature: QueryFeature, keys?: string[]) => IQueryLimitConfig[];
|
|
4
|
+
export declare const deny: (feature: QueryFeature, keys?: string[]) => IQueryLimitConfig[];
|
|
5
|
+
export declare const valideteQueryFeature: (model: IModelService, feature: QueryFeature, key?: string | null, errorDescription?: string) => void;
|
|
@@ -0,0 +1,116 @@
|
|
|
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
|
+
exports.valideteQueryFeature = exports.deny = exports.allow = void 0;
|
|
7
|
+
const Enums_1 = require("../Enums");
|
|
8
|
+
const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
9
|
+
const QueryFeatureMap = {
|
|
10
|
+
[Enums_1.QueryFeature.All]: [
|
|
11
|
+
Enums_1.QueryFeature.FieldsAll,
|
|
12
|
+
Enums_1.QueryFeature.Sorting,
|
|
13
|
+
Enums_1.QueryFeature.Limits,
|
|
14
|
+
Enums_1.QueryFeature.WhereEqual,
|
|
15
|
+
Enums_1.QueryFeature.WhereNotEqual,
|
|
16
|
+
Enums_1.QueryFeature.WhereGt,
|
|
17
|
+
Enums_1.QueryFeature.WhereGte,
|
|
18
|
+
Enums_1.QueryFeature.WhereLt,
|
|
19
|
+
Enums_1.QueryFeature.WhereLte,
|
|
20
|
+
Enums_1.QueryFeature.WhereLike,
|
|
21
|
+
Enums_1.QueryFeature.WhereNotLike,
|
|
22
|
+
Enums_1.QueryFeature.WhereIn,
|
|
23
|
+
Enums_1.QueryFeature.WhereNotIn,
|
|
24
|
+
Enums_1.QueryFeature.WhereBetween,
|
|
25
|
+
Enums_1.QueryFeature.WhereNotBetween,
|
|
26
|
+
Enums_1.QueryFeature.WhereNull,
|
|
27
|
+
Enums_1.QueryFeature.WhereNotNull,
|
|
28
|
+
Enums_1.QueryFeature.Trashed,
|
|
29
|
+
Enums_1.QueryFeature.WithHasOne,
|
|
30
|
+
Enums_1.QueryFeature.WithHasMany,
|
|
31
|
+
],
|
|
32
|
+
[Enums_1.QueryFeature.FieldsAll]: [Enums_1.QueryFeature.FieldsAll],
|
|
33
|
+
[Enums_1.QueryFeature.Sorting]: [Enums_1.QueryFeature.Sorting],
|
|
34
|
+
[Enums_1.QueryFeature.Limits]: [Enums_1.QueryFeature.Limits],
|
|
35
|
+
[Enums_1.QueryFeature.WhereAll]: [
|
|
36
|
+
Enums_1.QueryFeature.WhereEqual,
|
|
37
|
+
Enums_1.QueryFeature.WhereNotEqual,
|
|
38
|
+
Enums_1.QueryFeature.WhereGt,
|
|
39
|
+
Enums_1.QueryFeature.WhereGte,
|
|
40
|
+
Enums_1.QueryFeature.WhereLt,
|
|
41
|
+
Enums_1.QueryFeature.WhereLte,
|
|
42
|
+
Enums_1.QueryFeature.WhereLike,
|
|
43
|
+
Enums_1.QueryFeature.WhereNotLike,
|
|
44
|
+
Enums_1.QueryFeature.WhereIn,
|
|
45
|
+
Enums_1.QueryFeature.WhereNotIn,
|
|
46
|
+
Enums_1.QueryFeature.WhereBetween,
|
|
47
|
+
Enums_1.QueryFeature.WhereNotBetween,
|
|
48
|
+
Enums_1.QueryFeature.WhereNull,
|
|
49
|
+
Enums_1.QueryFeature.WhereNotNull,
|
|
50
|
+
],
|
|
51
|
+
[Enums_1.QueryFeature.WhereEqual]: [Enums_1.QueryFeature.WhereEqual],
|
|
52
|
+
[Enums_1.QueryFeature.WhereNotEqual]: [Enums_1.QueryFeature.WhereNotEqual],
|
|
53
|
+
[Enums_1.QueryFeature.WhereGt]: [Enums_1.QueryFeature.WhereGt],
|
|
54
|
+
[Enums_1.QueryFeature.WhereGte]: [Enums_1.QueryFeature.WhereGte],
|
|
55
|
+
[Enums_1.QueryFeature.WhereLt]: [Enums_1.QueryFeature.WhereLt],
|
|
56
|
+
[Enums_1.QueryFeature.WhereLte]: [Enums_1.QueryFeature.WhereLte],
|
|
57
|
+
[Enums_1.QueryFeature.WhereLike]: [Enums_1.QueryFeature.WhereLike],
|
|
58
|
+
[Enums_1.QueryFeature.WhereNotLike]: [Enums_1.QueryFeature.WhereNotLike],
|
|
59
|
+
[Enums_1.QueryFeature.WhereIn]: [Enums_1.QueryFeature.WhereIn],
|
|
60
|
+
[Enums_1.QueryFeature.WhereNotIn]: [Enums_1.QueryFeature.WhereNotIn],
|
|
61
|
+
[Enums_1.QueryFeature.WhereBetween]: [Enums_1.QueryFeature.WhereBetween],
|
|
62
|
+
[Enums_1.QueryFeature.WhereNotBetween]: [Enums_1.QueryFeature.WhereNotBetween],
|
|
63
|
+
[Enums_1.QueryFeature.WhereNull]: [Enums_1.QueryFeature.WhereNull],
|
|
64
|
+
[Enums_1.QueryFeature.WhereNotNull]: [Enums_1.QueryFeature.WhereNotNull],
|
|
65
|
+
[Enums_1.QueryFeature.Trashed]: [Enums_1.QueryFeature.Trashed],
|
|
66
|
+
[Enums_1.QueryFeature.WithAll]: [Enums_1.QueryFeature.WithHasOne, Enums_1.QueryFeature.WithHasMany],
|
|
67
|
+
[Enums_1.QueryFeature.WithHasOne]: [Enums_1.QueryFeature.WithHasOne],
|
|
68
|
+
[Enums_1.QueryFeature.WithHasMany]: [Enums_1.QueryFeature.WithHasMany],
|
|
69
|
+
};
|
|
70
|
+
const generatePermission = (type, feature, keys = []) => {
|
|
71
|
+
const features = QueryFeatureMap[feature];
|
|
72
|
+
if (keys.length === 0) {
|
|
73
|
+
keys = [null];
|
|
74
|
+
}
|
|
75
|
+
return features
|
|
76
|
+
.map((subFeature) => {
|
|
77
|
+
return keys.map((key) => {
|
|
78
|
+
return {
|
|
79
|
+
type,
|
|
80
|
+
feature: subFeature,
|
|
81
|
+
key,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
})
|
|
85
|
+
.flat();
|
|
86
|
+
};
|
|
87
|
+
const allow = (feature, keys = []) => {
|
|
88
|
+
return generatePermission(Enums_1.QueryFeatureType.Allow, feature, keys);
|
|
89
|
+
};
|
|
90
|
+
exports.allow = allow;
|
|
91
|
+
const deny = (feature, keys = []) => {
|
|
92
|
+
return generatePermission(Enums_1.QueryFeatureType.Deny, feature, keys);
|
|
93
|
+
};
|
|
94
|
+
exports.deny = deny;
|
|
95
|
+
const valideteQueryFeature = (model, feature, key = null, errorDescription) => {
|
|
96
|
+
const errorDetail = errorDescription ? ` (${errorDescription})` : "";
|
|
97
|
+
const rules = model.queryLimits.filter((limit) => limit.feature === feature && limit.key === null);
|
|
98
|
+
if (key) {
|
|
99
|
+
const keyRules = model.queryLimits.filter((limit) => limit.feature === feature && limit.key === key);
|
|
100
|
+
if (keyRules.length > 0) {
|
|
101
|
+
const lastKeyRule = keyRules[keyRules.length - 1];
|
|
102
|
+
if ((lastKeyRule === null || lastKeyRule === void 0 ? void 0 : lastKeyRule.type) === Enums_1.QueryFeatureType.Deny) {
|
|
103
|
+
throw new ApiError_1.default(`Unsupported query feature${errorDetail}: ${feature.toString()} [${key}]`);
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if (rules.length === 0) {
|
|
109
|
+
throw new ApiError_1.default(`Unsupported query feature${errorDetail}: ${feature.toString()}`);
|
|
110
|
+
}
|
|
111
|
+
const lastRule = rules[rules.length - 1];
|
|
112
|
+
if ((lastRule === null || lastRule === void 0 ? void 0 : lastRule.type) === Enums_1.QueryFeatureType.Deny) {
|
|
113
|
+
throw new ApiError_1.default(`Unsupported query feature${errorDetail}: ${feature.toString()}`);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
exports.valideteQueryFeature = valideteQueryFeature;
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { LogLevels } from "../Enums";
|
|
2
2
|
declare class LogService {
|
|
3
|
-
|
|
3
|
+
private static instance;
|
|
4
|
+
private level;
|
|
4
5
|
constructor(level: LogLevels);
|
|
6
|
+
static setInstance(level: LogLevels): void;
|
|
7
|
+
static getInstance(): LogService;
|
|
5
8
|
error(message: string): void;
|
|
6
9
|
warn(message: string): void;
|
|
7
10
|
info(message: string): void;
|
|
@@ -7,6 +7,12 @@ class LogService {
|
|
|
7
7
|
constructor(level) {
|
|
8
8
|
this.level = level;
|
|
9
9
|
}
|
|
10
|
+
static setInstance(level) {
|
|
11
|
+
LogService.instance = new LogService(level);
|
|
12
|
+
}
|
|
13
|
+
static getInstance() {
|
|
14
|
+
return LogService.instance;
|
|
15
|
+
}
|
|
10
16
|
error(message) {
|
|
11
17
|
if (this.level >= Enums_1.LogLevels.ERROR) {
|
|
12
18
|
console.error(fgRed, "[axe]", message, fgReset);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { HookFunctionTypes, Extensions } from "../Enums";
|
|
2
|
-
import { IColumn, IHookParameter, IModelService, IRelation } from "../Interfaces";
|
|
2
|
+
import { IColumn, IHookParameter, IModelService, IQueryLimitConfig, IRelation } from "../Interfaces";
|
|
3
3
|
import Model from "./../Model";
|
|
4
|
+
import { SerializationFunction } from "../Types";
|
|
4
5
|
declare class ModelService implements IModelService {
|
|
5
6
|
name: string;
|
|
6
7
|
instance: Model;
|
|
@@ -11,9 +12,13 @@ declare class ModelService implements IModelService {
|
|
|
11
12
|
events: Record<HookFunctionTypes, (params: IHookParameter) => void>;
|
|
12
13
|
children: IModelService[];
|
|
13
14
|
isRecursive: boolean;
|
|
15
|
+
queryLimits: IQueryLimitConfig[];
|
|
16
|
+
serialize: SerializationFunction | null;
|
|
14
17
|
constructor(name: string, instance: Model);
|
|
15
18
|
setColumns(columns: IColumn[]): void;
|
|
16
19
|
setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data: (params: IHookParameter) => void): void;
|
|
20
|
+
setQueryLimits(limits: IQueryLimitConfig[]): void;
|
|
21
|
+
setSerialization(callback: SerializationFunction): void;
|
|
17
22
|
private setHooks;
|
|
18
23
|
private setEvents;
|
|
19
24
|
}
|
|
@@ -12,6 +12,8 @@ class ModelService {
|
|
|
12
12
|
this.columnNames = [];
|
|
13
13
|
this.children = [];
|
|
14
14
|
this.isRecursive = false;
|
|
15
|
+
this.queryLimits = [];
|
|
16
|
+
this.serialize = null;
|
|
15
17
|
}
|
|
16
18
|
setColumns(columns) {
|
|
17
19
|
this.columns = columns;
|
|
@@ -28,6 +30,12 @@ class ModelService {
|
|
|
28
30
|
throw new Error("Undefined hook type.");
|
|
29
31
|
}
|
|
30
32
|
}
|
|
33
|
+
setQueryLimits(limits) {
|
|
34
|
+
this.queryLimits = limits;
|
|
35
|
+
}
|
|
36
|
+
setSerialization(callback) {
|
|
37
|
+
this.serialize = callback;
|
|
38
|
+
}
|
|
31
39
|
setHooks(hookFunctionType, data) {
|
|
32
40
|
this.hooks[hookFunctionType] = data;
|
|
33
41
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IQuery, ISortField, NestedWhere, IWhere, IModelService } from "../Interfaces";
|
|
1
|
+
import { IQuery, ISortField, NestedWhere, IWhere, IModelService, IVersionConfig } from "../Interfaces";
|
|
2
2
|
import { Knex } from "knex";
|
|
3
3
|
declare class QueryService {
|
|
4
4
|
model: IModelService;
|
|
@@ -6,7 +6,8 @@ declare class QueryService {
|
|
|
6
6
|
usedConditionColumns: string[];
|
|
7
7
|
relationColumns: string[];
|
|
8
8
|
createdJoins: string[];
|
|
9
|
-
|
|
9
|
+
config: IVersionConfig;
|
|
10
|
+
constructor(model: IModelService, models: IModelService[], config: IVersionConfig);
|
|
10
11
|
applyFields(query: Knex.QueryBuilder, fields: string[]): void;
|
|
11
12
|
applySorting(query: Knex.QueryBuilder, sort: ISortField[]): void;
|
|
12
13
|
applyWheresInsideGroup(sub: Knex.QueryBuilder, ruleSet: NestedWhere | IWhere): void;
|
|
@@ -6,10 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
const Enums_1 = require("../Enums");
|
|
7
7
|
const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
8
8
|
const Resolvers_1 = require("../Resolvers");
|
|
9
|
+
const constants_1 = require("../constants");
|
|
10
|
+
const LimitService_1 = require("./LimitService");
|
|
11
|
+
const Helpers_1 = require("../Handlers/Helpers");
|
|
9
12
|
class QueryService {
|
|
10
|
-
constructor(model, models) {
|
|
13
|
+
constructor(model, models, config) {
|
|
11
14
|
this.model = model;
|
|
12
15
|
this.models = models;
|
|
16
|
+
this.config = config;
|
|
13
17
|
this.createdJoins = [];
|
|
14
18
|
this.relationColumns = [];
|
|
15
19
|
this.usedConditionColumns = [];
|
|
@@ -17,6 +21,7 @@ class QueryService {
|
|
|
17
21
|
applyFields(query, fields) {
|
|
18
22
|
// Users should be able to select some fields to show.
|
|
19
23
|
if (fields.length === 0 || (fields.length === 1 && fields[0] === "*")) {
|
|
24
|
+
(0, LimitService_1.valideteQueryFeature)(this.model, Enums_1.QueryFeature.FieldsAll);
|
|
20
25
|
query.select(`${this.model.instance.table}.*`);
|
|
21
26
|
}
|
|
22
27
|
else {
|
|
@@ -33,7 +38,9 @@ class QueryService {
|
|
|
33
38
|
if (sort.length === 0) {
|
|
34
39
|
return;
|
|
35
40
|
}
|
|
41
|
+
(0, LimitService_1.valideteQueryFeature)(this.model, Enums_1.QueryFeature.Sorting);
|
|
36
42
|
sort.forEach((item) => {
|
|
43
|
+
(0, LimitService_1.valideteQueryFeature)(this.model, Enums_1.QueryFeature.Sorting, `${this.model.instance.table}.${item.name}`);
|
|
37
44
|
query.orderBy(item.name, item.type);
|
|
38
45
|
});
|
|
39
46
|
}
|
|
@@ -156,6 +163,7 @@ class QueryService {
|
|
|
156
163
|
this.createdJoins.push(relation.name);
|
|
157
164
|
}
|
|
158
165
|
parseSections(sections) {
|
|
166
|
+
var _a, _b, _c, _d;
|
|
159
167
|
if (sections.q) {
|
|
160
168
|
const queryContent = sections.q.replace(/%20/g, "").replace(/ /g, "");
|
|
161
169
|
// Users can send an unacceptable query string. We shouldn't allow them to
|
|
@@ -175,10 +183,14 @@ class QueryService {
|
|
|
175
183
|
sort: this.parseSortingOptions(sections.sort),
|
|
176
184
|
q: this.parseCondition(sections.q),
|
|
177
185
|
with: withQueryResolver.resolve((sections === null || sections === void 0 ? void 0 : sections.with) || ""),
|
|
178
|
-
trashed: (sections === null || sections === void 0 ? void 0 : sections.trashed)
|
|
179
|
-
? sections.trashed.trim() === "true" || sections.trashed.trim() === "1"
|
|
180
|
-
: false,
|
|
186
|
+
trashed: (sections === null || sections === void 0 ? void 0 : sections.trashed) ? (0, Helpers_1.isBoolean)(sections.trashed) : false,
|
|
181
187
|
};
|
|
188
|
+
const configPerPage = ((_b = (_a = this.config) === null || _a === void 0 ? void 0 : _a.query.defaults) === null || _b === void 0 ? void 0 : _b.perPage) ||
|
|
189
|
+
((_d = (_c = constants_1.DEFAULT_VERSION_CONFIG.query) === null || _c === void 0 ? void 0 : _c.defaults) === null || _d === void 0 ? void 0 : _d.perPage) ||
|
|
190
|
+
10;
|
|
191
|
+
if (query.per_page !== configPerPage) {
|
|
192
|
+
(0, LimitService_1.valideteQueryFeature)(this.model, Enums_1.QueryFeature.Limits);
|
|
193
|
+
}
|
|
182
194
|
this.addRelationColumns(query.with);
|
|
183
195
|
return query;
|
|
184
196
|
}
|
|
@@ -193,9 +205,21 @@ class QueryService {
|
|
|
193
205
|
return value;
|
|
194
206
|
}
|
|
195
207
|
parsePerPage(content) {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
208
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
209
|
+
const value = parseInt(content ||
|
|
210
|
+
((_b = (_a = this.config.query) === null || _a === void 0 ? void 0 : _a.defaults) === null || _b === void 0 ? void 0 : _b.perPage) ||
|
|
211
|
+
((_c = constants_1.DEFAULT_VERSION_CONFIG.query.defaults) === null || _c === void 0 ? void 0 : _c.perPage) ||
|
|
212
|
+
10);
|
|
213
|
+
const minPerPage = ((_e = (_d = this.config.query) === null || _d === void 0 ? void 0 : _d.defaults) === null || _e === void 0 ? void 0 : _e.minPerPage) ||
|
|
214
|
+
((_f = constants_1.DEFAULT_VERSION_CONFIG.query.defaults) === null || _f === void 0 ? void 0 : _f.minPerPage) ||
|
|
215
|
+
1;
|
|
216
|
+
const maxPerPage = ((_h = (_g = this.config.query) === null || _g === void 0 ? void 0 : _g.defaults) === null || _h === void 0 ? void 0 : _h.maxPerPage) ||
|
|
217
|
+
((_j = constants_1.DEFAULT_VERSION_CONFIG.query.defaults) === null || _j === void 0 ? void 0 : _j.maxPerPage) ||
|
|
218
|
+
100;
|
|
219
|
+
if (isNaN(value) || value <= minPerPage || value > maxPerPage) {
|
|
220
|
+
return (((_l = (_k = this.config.query) === null || _k === void 0 ? void 0 : _k.defaults) === null || _l === void 0 ? void 0 : _l.perPage) ||
|
|
221
|
+
((_m = constants_1.DEFAULT_VERSION_CONFIG.query.defaults) === null || _m === void 0 ? void 0 : _m.perPage) ||
|
|
222
|
+
10);
|
|
199
223
|
}
|
|
200
224
|
return value;
|
|
201
225
|
}
|
|
@@ -332,6 +356,7 @@ class QueryService {
|
|
|
332
356
|
where.relation = relation;
|
|
333
357
|
where.field = field;
|
|
334
358
|
}
|
|
359
|
+
(0, LimitService_1.valideteQueryFeature)(this.model, constants_1.ConditionQueryFeatureMap[where.condition], `${where.table}.${where.field}`);
|
|
335
360
|
this.shouldBeAcceptableColumn(where.field);
|
|
336
361
|
this.usedConditionColumns.push(`${where.table}.${where.field}`);
|
|
337
362
|
return where;
|
|
@@ -1,6 +1,13 @@
|
|
|
1
|
+
import { IVersion } from "../Interfaces";
|
|
1
2
|
declare class SchemaValidatorService {
|
|
3
|
+
private version;
|
|
4
|
+
constructor(version: IVersion);
|
|
2
5
|
validate(): Promise<void>;
|
|
3
6
|
private checkModelColumnsOrFail;
|
|
7
|
+
private checkRelationNamesOrFail;
|
|
8
|
+
private getQueryLimitRelations;
|
|
9
|
+
private getQueryLimitColumns;
|
|
10
|
+
private getQueryLimitKeyByFilter;
|
|
4
11
|
private getModelFillableColumns;
|
|
5
12
|
private getModelFormValidationColumns;
|
|
6
13
|
private getModelHiddenColumns;
|
|
@@ -8,11 +8,55 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
11
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const AxeError_1 = __importDefault(require("../Exceptions/AxeError"));
|
|
12
16
|
const Enums_1 = require("../Enums");
|
|
13
17
|
const Services_1 = require("../Services");
|
|
18
|
+
const COLUMN_BASED_QUERY_LIMITS = [
|
|
19
|
+
Enums_1.QueryFeature.Sorting,
|
|
20
|
+
Enums_1.QueryFeature.WhereEqual,
|
|
21
|
+
Enums_1.QueryFeature.WhereNotEqual,
|
|
22
|
+
Enums_1.QueryFeature.WhereGt,
|
|
23
|
+
Enums_1.QueryFeature.WhereGte,
|
|
24
|
+
Enums_1.QueryFeature.WhereLt,
|
|
25
|
+
Enums_1.QueryFeature.WhereLte,
|
|
26
|
+
Enums_1.QueryFeature.WhereLike,
|
|
27
|
+
Enums_1.QueryFeature.WhereNotLike,
|
|
28
|
+
Enums_1.QueryFeature.WhereIn,
|
|
29
|
+
Enums_1.QueryFeature.WhereNotIn,
|
|
30
|
+
Enums_1.QueryFeature.WhereBetween,
|
|
31
|
+
Enums_1.QueryFeature.WhereNotBetween,
|
|
32
|
+
Enums_1.QueryFeature.WhereNull,
|
|
33
|
+
Enums_1.QueryFeature.WhereNotNull,
|
|
34
|
+
];
|
|
35
|
+
const RELATION_BASED_QUERY_LIMITS = [
|
|
36
|
+
Enums_1.QueryFeature.WithHasMany,
|
|
37
|
+
Enums_1.QueryFeature.WithHasOne,
|
|
38
|
+
];
|
|
14
39
|
class SchemaValidatorService {
|
|
15
|
-
constructor() {
|
|
40
|
+
constructor(version) {
|
|
41
|
+
this.getQueryLimitRelations = (model) => {
|
|
42
|
+
return this.getQueryLimitKeyByFilter(model, RELATION_BASED_QUERY_LIMITS);
|
|
43
|
+
};
|
|
44
|
+
this.getQueryLimitColumns = (model) => {
|
|
45
|
+
return this.getQueryLimitKeyByFilter(model, COLUMN_BASED_QUERY_LIMITS);
|
|
46
|
+
};
|
|
47
|
+
this.getQueryLimitKeyByFilter = (model, filter) => {
|
|
48
|
+
const items = model.queryLimits
|
|
49
|
+
.filter((limit) => limit.key && filter.includes(limit.feature))
|
|
50
|
+
.map((limit) => limit.key)
|
|
51
|
+
.map((key) => {
|
|
52
|
+
if (!key) {
|
|
53
|
+
return "";
|
|
54
|
+
}
|
|
55
|
+
const [, field] = key === null || key === void 0 ? void 0 : key.split(".");
|
|
56
|
+
return field;
|
|
57
|
+
});
|
|
58
|
+
return items;
|
|
59
|
+
};
|
|
16
60
|
this.getModelFillableColumns = (model) => {
|
|
17
61
|
const fillable = model.instance.fillable;
|
|
18
62
|
if (!fillable) {
|
|
@@ -66,30 +110,40 @@ class SchemaValidatorService {
|
|
|
66
110
|
this.checkModelColumnsOrFail(model, [relation.primaryKey]);
|
|
67
111
|
const relatedModel = modelList.find(relation.model);
|
|
68
112
|
if (!relatedModel) {
|
|
69
|
-
throw new
|
|
113
|
+
throw new AxeError_1.default(Enums_1.AxeErrorCode.UNDEFINED_RELATION_MODEL, `Undefined related model: ${relation.model} (${model.name}.${relation.name})`);
|
|
70
114
|
}
|
|
71
115
|
this.checkModelColumnsOrFail(relatedModel, [relation.foreignKey]);
|
|
72
116
|
};
|
|
117
|
+
this.version = version;
|
|
73
118
|
}
|
|
74
119
|
validate() {
|
|
75
120
|
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
-
const logger =
|
|
77
|
-
|
|
78
|
-
modelList.get().forEach((model) => {
|
|
121
|
+
const logger = Services_1.LogService.getInstance();
|
|
122
|
+
this.version.modelList.get().forEach((model) => {
|
|
79
123
|
this.checkModelColumnsOrFail(model, this.getModelFillableColumns(model));
|
|
80
124
|
this.checkModelColumnsOrFail(model, this.getModelFormValidationColumns(model));
|
|
81
125
|
this.checkModelColumnsOrFail(model, this.getModelHiddenColumns(model));
|
|
82
126
|
this.checkModelColumnsOrFail(model, this.getTimestampsColumns(model));
|
|
127
|
+
this.checkModelColumnsOrFail(model, this.getQueryLimitColumns(model));
|
|
83
128
|
this.checkModelColumnsOrFail(model, [model.instance.primaryKey]);
|
|
84
|
-
this.
|
|
129
|
+
this.checkRelationNamesOrFail(model, this.getQueryLimitRelations(model));
|
|
130
|
+
this.checkRelationColumnsOrFail(this.version.modelList, model);
|
|
85
131
|
});
|
|
86
|
-
logger.info(
|
|
132
|
+
logger.info(`[${this.version.name}] Database schema has been validated.`);
|
|
87
133
|
});
|
|
88
134
|
}
|
|
89
135
|
checkModelColumnsOrFail(model, modelColumns) {
|
|
90
136
|
const undefinedColumns = modelColumns.filter((modelColumn) => !model.columnNames.includes(modelColumn));
|
|
91
137
|
if (undefinedColumns.length > 0) {
|
|
92
|
-
throw new
|
|
138
|
+
throw new AxeError_1.default(Enums_1.AxeErrorCode.UNDEFINED_COLUMN, `${model.name} model doesn't have the following columns on the database; "${model.instance.table}.${undefinedColumns.join(",")}"`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
checkRelationNamesOrFail(model, names) {
|
|
142
|
+
const undefinedRelationNames = names.filter((name) => {
|
|
143
|
+
return !model.relations.map((relation) => relation.name).includes(name);
|
|
144
|
+
});
|
|
145
|
+
if (undefinedRelationNames.length > 0) {
|
|
146
|
+
throw new AxeError_1.default(Enums_1.AxeErrorCode.UNDEFINED_RELATION_NAME, `${model.name} model doesn't have a valid relation name that is defined in query limits; "${undefinedRelationNames.join(",")}"`);
|
|
93
147
|
}
|
|
94
148
|
}
|
|
95
149
|
checkRelationColumnsOrFail(modelList, model) {
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import APIService from "./APIService";
|
|
1
2
|
import DocumentationService from "./DocumentationService";
|
|
2
3
|
import IoCService from "./IoCService";
|
|
4
|
+
import { allow, deny } from "./LimitService";
|
|
3
5
|
import LogService from "./LogService";
|
|
4
6
|
import ModelListService from "./ModelListService";
|
|
5
7
|
import ModelService from "./ModelService";
|
|
6
8
|
import QueryService from "./QueryService";
|
|
7
9
|
import SchemaValidatorService from "./SchemaValidatorService";
|
|
8
|
-
export { DocumentationService, IoCService, LogService, ModelListService, ModelService, QueryService, SchemaValidatorService, };
|
|
10
|
+
export { DocumentationService, APIService, IoCService, LogService, ModelListService, ModelService, QueryService, SchemaValidatorService, allow, deny, };
|
|
@@ -3,11 +3,16 @@ 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
|
-
exports.SchemaValidatorService = exports.QueryService = exports.ModelService = exports.ModelListService = exports.LogService = exports.IoCService = exports.DocumentationService = void 0;
|
|
6
|
+
exports.deny = exports.allow = exports.SchemaValidatorService = exports.QueryService = exports.ModelService = exports.ModelListService = exports.LogService = exports.IoCService = exports.APIService = exports.DocumentationService = void 0;
|
|
7
|
+
const APIService_1 = __importDefault(require("./APIService"));
|
|
8
|
+
exports.APIService = APIService_1.default;
|
|
7
9
|
const DocumentationService_1 = __importDefault(require("./DocumentationService"));
|
|
8
10
|
exports.DocumentationService = DocumentationService_1.default;
|
|
9
11
|
const IoCService_1 = __importDefault(require("./IoCService"));
|
|
10
12
|
exports.IoCService = IoCService_1.default;
|
|
13
|
+
const LimitService_1 = require("./LimitService");
|
|
14
|
+
Object.defineProperty(exports, "allow", { enumerable: true, get: function () { return LimitService_1.allow; } });
|
|
15
|
+
Object.defineProperty(exports, "deny", { enumerable: true, get: function () { return LimitService_1.deny; } });
|
|
11
16
|
const LogService_1 = __importDefault(require("./LogService"));
|
|
12
17
|
exports.LogService = LogService_1.default;
|
|
13
18
|
const ModelListService_1 = __importDefault(require("./ModelListService"));
|
package/build/src/constants.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { HandlerTypes } from "./Enums";
|
|
1
|
+
import { ConditionTypes, HandlerTypes, QueryFeature, Relationships } from "./Enums";
|
|
2
|
+
import { IVersionConfig } from "./Interfaces";
|
|
2
3
|
export declare const LOG_COLORS: {
|
|
3
4
|
fgBlack: string;
|
|
4
5
|
fgRed: string;
|
|
@@ -22,3 +23,6 @@ export declare const API_ROUTE_TEMPLATES: {
|
|
|
22
23
|
destroy: (prefix: string, parentUrl: string, resource: string, primaryKey: string) => string;
|
|
23
24
|
force_delete: (prefix: string, parentUrl: string, resource: string, primaryKey: string) => string;
|
|
24
25
|
};
|
|
26
|
+
export declare const ConditionQueryFeatureMap: Record<ConditionTypes, QueryFeature>;
|
|
27
|
+
export declare const RelationQueryFeatureMap: Record<Relationships, QueryFeature>;
|
|
28
|
+
export declare const DEFAULT_VERSION_CONFIG: IVersionConfig;
|
package/build/src/constants.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.API_ROUTE_TEMPLATES = exports.DEFAULT_METHODS_OF_MODELS = exports.DEFAULT_HANDLERS = exports.LOG_COLORS = void 0;
|
|
3
|
+
exports.DEFAULT_VERSION_CONFIG = exports.RelationQueryFeatureMap = exports.ConditionQueryFeatureMap = exports.API_ROUTE_TEMPLATES = exports.DEFAULT_METHODS_OF_MODELS = exports.DEFAULT_HANDLERS = exports.LOG_COLORS = void 0;
|
|
4
4
|
const Enums_1 = require("./Enums");
|
|
5
|
+
const LimitService_1 = require("./Services/LimitService");
|
|
5
6
|
exports.LOG_COLORS = {
|
|
6
7
|
fgBlack: "\x1b[30m",
|
|
7
8
|
fgRed: "\x1b[31m",
|
|
@@ -26,7 +27,6 @@ exports.DEFAULT_METHODS_OF_MODELS = [
|
|
|
26
27
|
"hasMany",
|
|
27
28
|
"hasOne",
|
|
28
29
|
"belongsTo",
|
|
29
|
-
"serialize",
|
|
30
30
|
"__defineGetter__",
|
|
31
31
|
"__defineSetter__",
|
|
32
32
|
"hasOwnProperty",
|
|
@@ -49,6 +49,7 @@ exports.DEFAULT_METHODS_OF_MODELS = [
|
|
|
49
49
|
"deletedAtColumn",
|
|
50
50
|
"transaction",
|
|
51
51
|
"ignore",
|
|
52
|
+
"limits",
|
|
52
53
|
"getFillableFields",
|
|
53
54
|
"getValidationRules",
|
|
54
55
|
];
|
|
@@ -62,3 +63,43 @@ exports.API_ROUTE_TEMPLATES = {
|
|
|
62
63
|
[Enums_1.HandlerTypes.DELETE]: (prefix, parentUrl, resource, primaryKey) => `/${prefix}/${parentUrl}${resource}/:${primaryKey}`,
|
|
63
64
|
[Enums_1.HandlerTypes.FORCE_DELETE]: (prefix, parentUrl, resource, primaryKey) => `/${prefix}/${parentUrl}${resource}/:${primaryKey}/force`,
|
|
64
65
|
};
|
|
66
|
+
exports.ConditionQueryFeatureMap = {
|
|
67
|
+
[Enums_1.ConditionTypes.NotNull]: Enums_1.QueryFeature.WhereNotNull,
|
|
68
|
+
[Enums_1.ConditionTypes.Null]: Enums_1.QueryFeature.WhereNull,
|
|
69
|
+
[Enums_1.ConditionTypes["="]]: Enums_1.QueryFeature.WhereEqual,
|
|
70
|
+
[Enums_1.ConditionTypes["<>"]]: Enums_1.QueryFeature.WhereNotEqual,
|
|
71
|
+
[Enums_1.ConditionTypes[">"]]: Enums_1.QueryFeature.WhereGt,
|
|
72
|
+
[Enums_1.ConditionTypes[">="]]: Enums_1.QueryFeature.WhereGte,
|
|
73
|
+
[Enums_1.ConditionTypes["<"]]: Enums_1.QueryFeature.WhereLt,
|
|
74
|
+
[Enums_1.ConditionTypes["<="]]: Enums_1.QueryFeature.WhereLte,
|
|
75
|
+
[Enums_1.ConditionTypes["LIKE"]]: Enums_1.QueryFeature.WhereLike,
|
|
76
|
+
[Enums_1.ConditionTypes["NOT LIKE"]]: Enums_1.QueryFeature.WhereNotLike,
|
|
77
|
+
[Enums_1.ConditionTypes["In"]]: Enums_1.QueryFeature.WhereIn,
|
|
78
|
+
[Enums_1.ConditionTypes["NotIn"]]: Enums_1.QueryFeature.WhereNotIn,
|
|
79
|
+
[Enums_1.ConditionTypes["Between"]]: Enums_1.QueryFeature.WhereBetween,
|
|
80
|
+
[Enums_1.ConditionTypes["NotBetween"]]: Enums_1.QueryFeature.WhereNotBetween,
|
|
81
|
+
};
|
|
82
|
+
exports.RelationQueryFeatureMap = {
|
|
83
|
+
[Enums_1.Relationships.HAS_ONE]: Enums_1.QueryFeature.WithHasOne,
|
|
84
|
+
[Enums_1.Relationships.HAS_MANY]: Enums_1.QueryFeature.WithHasMany,
|
|
85
|
+
};
|
|
86
|
+
exports.DEFAULT_VERSION_CONFIG = {
|
|
87
|
+
transaction: false,
|
|
88
|
+
serializers: [],
|
|
89
|
+
supportedLanguages: ["en"],
|
|
90
|
+
defaultLanguage: "en",
|
|
91
|
+
query: {
|
|
92
|
+
limits: [
|
|
93
|
+
(0, LimitService_1.allow)(Enums_1.QueryFeature.All),
|
|
94
|
+
(0, LimitService_1.deny)(Enums_1.QueryFeature.WithHasMany),
|
|
95
|
+
(0, LimitService_1.deny)(Enums_1.QueryFeature.WhereLike),
|
|
96
|
+
(0, LimitService_1.deny)(Enums_1.QueryFeature.WhereNotLike),
|
|
97
|
+
(0, LimitService_1.deny)(Enums_1.QueryFeature.Trashed),
|
|
98
|
+
],
|
|
99
|
+
defaults: {
|
|
100
|
+
perPage: 10,
|
|
101
|
+
minPerPage: 1,
|
|
102
|
+
maxPerPage: 100,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|