axe-api 0.31.2 → 0.31.4
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/src/Builders/RouterBuilder.js +14 -16
- package/build/src/Handlers/DestroyHandler.js +2 -3
- package/build/src/Handlers/ForceDestroyHandler.js +2 -3
- package/build/src/Handlers/HandlerFactory.d.ts +2 -2
- package/build/src/Handlers/Helpers.d.ts +3 -4
- package/build/src/Handlers/Helpers.js +5 -4
- package/build/src/Handlers/PatchHandler.js +2 -3
- package/build/src/Handlers/ShowHandler.js +1 -2
- package/build/src/Handlers/StoreHandler.js +4 -1
- package/build/src/Handlers/UpdateHandler.js +2 -3
- package/build/src/Interfaces.d.ts +7 -7
- package/build/src/Model.d.ts +7 -7
- package/build/src/Model.js +7 -5
- package/build/src/Resolvers/GeneralHookResolver.js +1 -1
- package/build/src/Services/DocumentationService.js +2 -2
- package/build/src/Services/LogService.d.ts +1 -1
- package/build/src/Services/LogService.js +3 -5
- package/build/src/Services/ModelService.d.ts +5 -5
- package/build/src/Services/QueryService.js +2 -10
- package/build/src/Types.d.ts +7 -1
- package/build/src/constants.d.ts +1 -0
- package/build/src/constants.js +2 -1
- package/package.json +4 -1
- package/readme.md +10 -124
- package/CHANGELOG.md +0 -263
|
@@ -32,11 +32,11 @@ class RouterBuilder {
|
|
|
32
32
|
this.getRootPrefix = () => __awaiter(this, void 0, void 0, function* () {
|
|
33
33
|
const api = Services_1.APIService.getInstance();
|
|
34
34
|
let prefix = api.config.prefix || "api";
|
|
35
|
-
if (prefix.
|
|
36
|
-
prefix = prefix.
|
|
35
|
+
if (prefix.startsWith("/")) {
|
|
36
|
+
prefix = prefix.substring(1);
|
|
37
37
|
}
|
|
38
|
-
if (prefix.
|
|
39
|
-
prefix = prefix.
|
|
38
|
+
if (prefix.endsWith("/")) {
|
|
39
|
+
prefix = prefix.substring(0, prefix.length - 1);
|
|
40
40
|
}
|
|
41
41
|
return prefix;
|
|
42
42
|
});
|
|
@@ -210,19 +210,17 @@ class RouterBuilder {
|
|
|
210
210
|
}
|
|
211
211
|
sendErrorAsResponse(res, error) {
|
|
212
212
|
const type = error.type;
|
|
213
|
-
|
|
214
|
-
case
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
break;
|
|
221
|
-
default:
|
|
222
|
-
// We should log error and send general error response
|
|
223
|
-
Services_1.LogService.getInstance().error(`SERVER ERROR: ${JSON.stringify(Object.assign(Object.assign({}, error), { message: error.message }), null, " ")}`);
|
|
224
|
-
throw error;
|
|
213
|
+
if (type === "ApiError") {
|
|
214
|
+
// eslint-disable-next-line no-case-declarations
|
|
215
|
+
const apiError = error;
|
|
216
|
+
res.status(apiError.status).json({
|
|
217
|
+
error: apiError.message,
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
225
220
|
}
|
|
221
|
+
// We should log error and send general error response
|
|
222
|
+
Services_1.LogService.getInstance().error(`SERVER ERROR: ${JSON.stringify(Object.assign(Object.assign({}, error), { message: error.message }), null, " ")}`);
|
|
223
|
+
throw error;
|
|
226
224
|
}
|
|
227
225
|
getResourcePath(model, relation) {
|
|
228
226
|
return relation
|
|
@@ -15,7 +15,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const Helpers_1 = require("./Helpers");
|
|
16
16
|
const Enums_1 = require("../Enums");
|
|
17
17
|
const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
18
|
-
const Enums_2 = require("../Enums");
|
|
19
18
|
exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
19
|
const { model, req, res, database, relation, parentModel } = pack;
|
|
21
20
|
// We should check the parameter type
|
|
@@ -32,7 +31,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
32
31
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onBeforeDeleteQuery, Object.assign(Object.assign({}, pack), { query }));
|
|
33
32
|
const item = yield query.first();
|
|
34
33
|
if (!item) {
|
|
35
|
-
throw new ApiError_1.default(`The item is not found on ${model.name}.`,
|
|
34
|
+
throw new ApiError_1.default(`The item is not found on ${model.name}.`, Enums_1.StatusCodes.NOT_FOUND);
|
|
36
35
|
}
|
|
37
36
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterDeleteQuery, Object.assign(Object.assign({}, pack), { query,
|
|
38
37
|
item }));
|
|
@@ -48,5 +47,5 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
48
47
|
yield query.delete();
|
|
49
48
|
}
|
|
50
49
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterDelete, Object.assign(Object.assign({}, pack), { item }));
|
|
51
|
-
return res.json();
|
|
50
|
+
return res.status(204).json();
|
|
52
51
|
});
|
|
@@ -15,7 +15,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
15
15
|
const Helpers_1 = require("./Helpers");
|
|
16
16
|
const Enums_1 = require("../Enums");
|
|
17
17
|
const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
18
|
-
const Enums_2 = require("../Enums");
|
|
19
18
|
exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
20
19
|
const { model, req, res, database, relation, parentModel } = pack;
|
|
21
20
|
// We should check the parameter type
|
|
@@ -27,7 +26,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
27
26
|
.where(model.instance.primaryKey, value);
|
|
28
27
|
// If there is a deletedAtColumn, it means that this table support soft-delete
|
|
29
28
|
if (model.instance.deletedAtColumn === null) {
|
|
30
|
-
throw new ApiError_1.default("You can use force delete only soft-delete supported models.",
|
|
29
|
+
throw new ApiError_1.default("You can use force delete only soft-delete supported models.", Enums_1.StatusCodes.NOT_FOUND);
|
|
31
30
|
}
|
|
32
31
|
// If there is a relation, we should bind it
|
|
33
32
|
(0, Helpers_1.addForeignKeyQuery)(req, query, relation, parentModel);
|
|
@@ -42,5 +41,5 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
42
41
|
item }));
|
|
43
42
|
yield query.delete();
|
|
44
43
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterForceDelete, Object.assign(Object.assign({}, pack), { item }));
|
|
45
|
-
return res.json();
|
|
44
|
+
return res.status(204).json();
|
|
46
45
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { IRequestPack } from "../Interfaces";
|
|
2
1
|
import { HandlerTypes } from "../Enums";
|
|
2
|
+
import { HandlerFunction } from "../Types";
|
|
3
3
|
declare class HandlerFactory {
|
|
4
|
-
static get(handleType: HandlerTypes):
|
|
4
|
+
static get(handleType: HandlerTypes): HandlerFunction;
|
|
5
5
|
}
|
|
6
6
|
export default HandlerFactory;
|
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { Request } from "express";
|
|
2
|
-
import { IModelService, IRelation, IHookParameter, IQuery, IVersion } from "../Interfaces";
|
|
2
|
+
import { IModelService, IRelation, IHookParameter, IQuery, IVersion, IWith } from "../Interfaces";
|
|
3
3
|
import { Knex } from "knex";
|
|
4
|
-
import { IWith } from "../Interfaces";
|
|
5
4
|
import { HandlerTypes, HookFunctionTypes, TimestampColumns } from "../Enums";
|
|
6
5
|
import { ModelListService } from "../Services";
|
|
7
6
|
import { SerializationFunction } from "../Types";
|
|
8
|
-
export declare const bindTimestampValues: (formData: Record<string, any>,
|
|
7
|
+
export declare const bindTimestampValues: (formData: Record<string, any>, model: IModelService, columnTypes?: TimestampColumns[]) => void;
|
|
9
8
|
export declare const getMergedFormData: (req: Request, fillables: string[]) => Record<string, any>;
|
|
10
9
|
export declare const callHooks: (model: IModelService, type: HookFunctionTypes, params: IHookParameter) => Promise<void>;
|
|
11
10
|
export declare const getParentColumn: (relation: IRelation | null) => string | null;
|
|
12
11
|
export declare const checkPrimaryKeyValueType: (model: IModelService, value: any) => void;
|
|
13
12
|
export declare const addForeignKeyQuery: (request: Request, query: Knex.QueryBuilder, relation: IRelation | null, parentModel: IModelService | null) => void;
|
|
14
|
-
export declare const serializeData: (version: IVersion, itemArray: any
|
|
13
|
+
export declare const serializeData: (version: IVersion, itemArray: any, modelSerializer: SerializationFunction | null, handler: HandlerTypes, request: Request) => Promise<any[]>;
|
|
15
14
|
export declare const filterHiddenFields: (itemArray: any[], hiddens: string[] | null) => void;
|
|
16
15
|
export declare const addSoftDeleteQuery: (model: IModelService, conditions: IQuery | null, query: Knex.QueryBuilder) => void;
|
|
17
16
|
export declare const getRelatedData: (version: IVersion, data: any[], withArray: IWith[], model: IModelService, modelList: ModelListService, database: Knex | Knex.Transaction, handler: HandlerTypes, request: Request) => Promise<void>;
|
|
@@ -19,7 +19,7 @@ const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
|
19
19
|
const Services_1 = require("../Services");
|
|
20
20
|
const LimitService_1 = require("../Services/LimitService");
|
|
21
21
|
const constants_1 = require("../constants");
|
|
22
|
-
const bindTimestampValues = (formData, columnTypes = []
|
|
22
|
+
const bindTimestampValues = (formData, model, columnTypes = []) => {
|
|
23
23
|
if (columnTypes.includes(Enums_1.TimestampColumns.CREATED_AT) &&
|
|
24
24
|
model.instance.createdAtColumn) {
|
|
25
25
|
formData[model.instance.createdAtColumn] = new Date();
|
|
@@ -42,7 +42,8 @@ const getMergedFormData = (req, fillables) => {
|
|
|
42
42
|
exports.getMergedFormData = getMergedFormData;
|
|
43
43
|
const callHooks = (model, type, params) => __awaiter(void 0, void 0, void 0, function* () {
|
|
44
44
|
if (model.hooks[type]) {
|
|
45
|
-
|
|
45
|
+
const hookFunction = model.hooks[type];
|
|
46
|
+
yield hookFunction(params);
|
|
46
47
|
}
|
|
47
48
|
if (model.events[type]) {
|
|
48
49
|
// Developers shouldn't be able to access transaction in events. Because
|
|
@@ -66,7 +67,8 @@ exports.getParentColumn = getParentColumn;
|
|
|
66
67
|
const checkPrimaryKeyValueType = (model, value) => {
|
|
67
68
|
// We should check the parameter type
|
|
68
69
|
const primaryColumn = model.columns.find((column) => column.name === model.instance.primaryKey);
|
|
69
|
-
if ((primaryColumn === null || primaryColumn === void 0 ? void 0 : primaryColumn.data_type)
|
|
70
|
+
if (constants_1.NUMERIC_PRIMARY_KEY_TYPES.includes((primaryColumn === null || primaryColumn === void 0 ? void 0 : primaryColumn.data_type) || "") &&
|
|
71
|
+
isNaN(parseInt(value))) {
|
|
70
72
|
throw new ApiError_1.default(`Unacceptable parameter: ${value}`);
|
|
71
73
|
}
|
|
72
74
|
};
|
|
@@ -117,7 +119,6 @@ const globalSerializer = (version, itemArray, handler, request) => __awaiter(voi
|
|
|
117
119
|
// Serialize data with specific handler like "PAGINATE" or "SHOW".
|
|
118
120
|
if (configSerializer.handler.includes(handler)) {
|
|
119
121
|
callbacks.push(...configSerializer.serializer);
|
|
120
|
-
return;
|
|
121
122
|
}
|
|
122
123
|
});
|
|
123
124
|
callbacks.forEach((callback) => {
|
|
@@ -16,7 +16,6 @@ const validatorjs_1 = __importDefault(require("validatorjs"));
|
|
|
16
16
|
const Helpers_1 = require("./Helpers");
|
|
17
17
|
const Enums_1 = require("../Enums");
|
|
18
18
|
const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
19
|
-
const Enums_2 = require("../Enums");
|
|
20
19
|
exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
20
|
const { version, model, req, res, database, relation, parentModel } = pack;
|
|
22
21
|
const query = database.from(model.instance.table);
|
|
@@ -31,7 +30,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
31
30
|
// Adding the main query
|
|
32
31
|
let item = yield query.where(model.instance.primaryKey, value).first();
|
|
33
32
|
if (!item) {
|
|
34
|
-
throw new ApiError_1.default(`The item is not found on ${model.name}.`,
|
|
33
|
+
throw new ApiError_1.default(`The item is not found on ${model.name}.`, Enums_1.StatusCodes.NOT_FOUND);
|
|
35
34
|
}
|
|
36
35
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterUpdateQuery, Object.assign(Object.assign({}, pack), { item,
|
|
37
36
|
query }));
|
|
@@ -49,7 +48,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
// We should bind the timestamp values
|
|
52
|
-
(0, Helpers_1.bindTimestampValues)(formData, [Enums_1.TimestampColumns.UPDATED_AT]
|
|
51
|
+
(0, Helpers_1.bindTimestampValues)(formData, model, [Enums_1.TimestampColumns.UPDATED_AT]);
|
|
53
52
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onBeforeUpdate, Object.assign(Object.assign({}, pack), { item,
|
|
54
53
|
formData,
|
|
55
54
|
query }));
|
|
@@ -16,7 +16,6 @@ const Helpers_1 = require("./Helpers");
|
|
|
16
16
|
const Enums_1 = require("../Enums");
|
|
17
17
|
const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
18
18
|
const Services_1 = require("../Services");
|
|
19
|
-
const Enums_2 = require("../Enums");
|
|
20
19
|
exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
20
|
const { version, model, req, res, database, relation, parentModel } = pack;
|
|
22
21
|
const queryParser = new Services_1.QueryService(model, version.modelList.get(), version.config);
|
|
@@ -41,7 +40,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
41
40
|
queryParser.applyWheres(query, conditions.q);
|
|
42
41
|
let item = yield query.first();
|
|
43
42
|
if (!item) {
|
|
44
|
-
throw new ApiError_1.default(`The item is not found on ${model.name}.`,
|
|
43
|
+
throw new ApiError_1.default(`The item is not found on ${model.name}.`, Enums_1.StatusCodes.NOT_FOUND);
|
|
45
44
|
}
|
|
46
45
|
// We should try to get related data if there is any
|
|
47
46
|
yield (0, Helpers_1.getRelatedData)(version, [item], conditions.with, model, version.modelList, database, Enums_1.HandlerTypes.ALL, req);
|
|
@@ -37,7 +37,10 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
39
|
// We should bind the timestamp values
|
|
40
|
-
(0, Helpers_1.bindTimestampValues)(formData,
|
|
40
|
+
(0, Helpers_1.bindTimestampValues)(formData, model, [
|
|
41
|
+
Enums_1.TimestampColumns.CREATED_AT,
|
|
42
|
+
Enums_1.TimestampColumns.UPDATED_AT,
|
|
43
|
+
]);
|
|
41
44
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onBeforeInsert, Object.assign(Object.assign({}, pack), { formData }));
|
|
42
45
|
const [returningResult] = yield database(model.instance.table)
|
|
43
46
|
.insert(formData)
|
|
@@ -16,7 +16,6 @@ const validatorjs_1 = __importDefault(require("validatorjs"));
|
|
|
16
16
|
const Helpers_1 = require("./Helpers");
|
|
17
17
|
const Enums_1 = require("../Enums");
|
|
18
18
|
const ApiError_1 = __importDefault(require("../Exceptions/ApiError"));
|
|
19
|
-
const Enums_2 = require("../Enums");
|
|
20
19
|
exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
20
|
const { version, model, req, res, database, relation, parentModel } = pack;
|
|
22
21
|
const query = database.from(model.instance.table);
|
|
@@ -31,7 +30,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
31
30
|
// Adding the main query
|
|
32
31
|
let item = yield query.where(model.instance.primaryKey, value).first();
|
|
33
32
|
if (!item) {
|
|
34
|
-
throw new ApiError_1.default(`The item is not found on ${model.name}.`,
|
|
33
|
+
throw new ApiError_1.default(`The item is not found on ${model.name}.`, Enums_1.StatusCodes.NOT_FOUND);
|
|
35
34
|
}
|
|
36
35
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onAfterUpdateQuery, Object.assign(Object.assign({}, pack), { item,
|
|
37
36
|
query }));
|
|
@@ -49,7 +48,7 @@ exports.default = (pack) => __awaiter(void 0, void 0, void 0, function* () {
|
|
|
49
48
|
}
|
|
50
49
|
}
|
|
51
50
|
// We should bind the timestamp values
|
|
52
|
-
(0, Helpers_1.bindTimestampValues)(formData, [Enums_1.TimestampColumns.UPDATED_AT]
|
|
51
|
+
(0, Helpers_1.bindTimestampValues)(formData, model, [Enums_1.TimestampColumns.UPDATED_AT]);
|
|
53
52
|
yield (0, Helpers_1.callHooks)(model, Enums_1.HookFunctionTypes.onBeforeUpdate, Object.assign(Object.assign({}, pack), { item,
|
|
54
53
|
formData,
|
|
55
54
|
query }));
|
|
@@ -3,7 +3,7 @@ import { Express, Request, Response, NextFunction } from "express";
|
|
|
3
3
|
import { Column } from "knex-schema-inspector/lib/types/column";
|
|
4
4
|
import { HandlerTypes, LogLevels, HttpMethods, HookFunctionTypes, Extensions, Relationships, SortTypes, ConditionTypes, DependencyTypes, QueryFeature, QueryFeatureType } from "./Enums";
|
|
5
5
|
import Model from "./Model";
|
|
6
|
-
import { SerializationFunction } from "./Types";
|
|
6
|
+
import { HookFunction, SerializationFunction } from "./Types";
|
|
7
7
|
import { ModelListService } from "./Services";
|
|
8
8
|
export interface IColumn extends Column {
|
|
9
9
|
table_name: string;
|
|
@@ -96,9 +96,9 @@ export interface IHookParameter {
|
|
|
96
96
|
database: Knex | Knex.Transaction;
|
|
97
97
|
conditions: IQuery | null;
|
|
98
98
|
query: Knex.QueryBuilder | null;
|
|
99
|
-
result: any
|
|
100
|
-
item: any
|
|
101
|
-
formData: any
|
|
99
|
+
result: any;
|
|
100
|
+
item: any;
|
|
101
|
+
formData: any;
|
|
102
102
|
}
|
|
103
103
|
export interface IMethodBaseConfig {
|
|
104
104
|
[HttpMethods.POST]?: string[];
|
|
@@ -115,14 +115,14 @@ export interface IModelService {
|
|
|
115
115
|
relations: IRelation[];
|
|
116
116
|
columns: IColumn[];
|
|
117
117
|
columnNames: string[];
|
|
118
|
-
hooks: Record<HookFunctionTypes,
|
|
119
|
-
events: Record<HookFunctionTypes,
|
|
118
|
+
hooks: Record<HookFunctionTypes, HookFunction>;
|
|
119
|
+
events: Record<HookFunctionTypes, HookFunction>;
|
|
120
120
|
isRecursive: boolean;
|
|
121
121
|
children: IModelService[];
|
|
122
122
|
queryLimits: IQueryLimitConfig[];
|
|
123
123
|
serialize: SerializationFunction | null;
|
|
124
124
|
setColumns(columns: IColumn[]): void;
|
|
125
|
-
setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data:
|
|
125
|
+
setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data: HookFunction): void;
|
|
126
126
|
setQueryLimits(limits: IQueryLimitConfig[]): void;
|
|
127
127
|
setSerialization(callback: SerializationFunction): void;
|
|
128
128
|
}
|
package/build/src/Model.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from "express";
|
|
2
1
|
import { IRelation, IMethodBaseConfig, IMethodBaseValidations, IHandlerBaseMiddleware, IHandlerBasedTransactionConfig, IQueryLimitConfig } from "./Interfaces";
|
|
3
2
|
import { HandlerTypes, HttpMethods } from "./Enums";
|
|
3
|
+
import { FieldList, MiddlewareFunction, ModelValidation } from "./Types";
|
|
4
4
|
declare class Model {
|
|
5
5
|
get primaryKey(): string;
|
|
6
6
|
get table(): string;
|
|
7
|
-
get fillable():
|
|
8
|
-
get validations(): IMethodBaseValidations |
|
|
7
|
+
get fillable(): FieldList | IMethodBaseConfig;
|
|
8
|
+
get validations(): IMethodBaseValidations | ModelValidation;
|
|
9
9
|
get handlers(): HandlerTypes[];
|
|
10
|
-
get middlewares():
|
|
11
|
-
get hiddens():
|
|
10
|
+
get middlewares(): MiddlewareFunction[] | IHandlerBaseMiddleware[] | IHandlerBaseMiddleware;
|
|
11
|
+
get hiddens(): FieldList;
|
|
12
12
|
get createdAtColumn(): string | null;
|
|
13
13
|
get updatedAtColumn(): string | null;
|
|
14
14
|
get deletedAtColumn(): string | null;
|
|
@@ -16,8 +16,8 @@ declare class Model {
|
|
|
16
16
|
get ignore(): boolean;
|
|
17
17
|
get limits(): Array<IQueryLimitConfig[]>;
|
|
18
18
|
getFillableFields(methodType: HttpMethods): string[];
|
|
19
|
-
getValidationRules(methodType: HttpMethods):
|
|
20
|
-
getMiddlewares(handlerType: HandlerTypes):
|
|
19
|
+
getValidationRules(methodType: HttpMethods): ModelValidation | null;
|
|
20
|
+
getMiddlewares(handlerType: HandlerTypes): MiddlewareFunction[];
|
|
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;
|
package/build/src/Model.js
CHANGED
|
@@ -48,6 +48,7 @@ class Model {
|
|
|
48
48
|
return [];
|
|
49
49
|
}
|
|
50
50
|
getFillableFields(methodType) {
|
|
51
|
+
var _a, _b, _c;
|
|
51
52
|
if (this.fillable === null) {
|
|
52
53
|
return [];
|
|
53
54
|
}
|
|
@@ -57,26 +58,27 @@ class Model {
|
|
|
57
58
|
const values = this.fillable;
|
|
58
59
|
switch (methodType) {
|
|
59
60
|
case Enums_1.HttpMethods.PATCH:
|
|
60
|
-
return values.PATCH
|
|
61
|
+
return (_a = values.PATCH) !== null && _a !== void 0 ? _a : [];
|
|
61
62
|
case Enums_1.HttpMethods.POST:
|
|
62
|
-
return values.POST
|
|
63
|
+
return (_b = values.POST) !== null && _b !== void 0 ? _b : [];
|
|
63
64
|
case Enums_1.HttpMethods.PUT:
|
|
64
|
-
return values.PUT
|
|
65
|
+
return (_c = values.PUT) !== null && _c !== void 0 ? _c : [];
|
|
65
66
|
default:
|
|
66
67
|
return [];
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
getValidationRules(methodType) {
|
|
71
|
+
var _a, _b;
|
|
70
72
|
if (this.hasStringValue()) {
|
|
71
73
|
return this.validations;
|
|
72
74
|
}
|
|
73
75
|
const values = this.validations;
|
|
74
76
|
switch (methodType) {
|
|
75
77
|
case Enums_1.HttpMethods.POST:
|
|
76
|
-
return values.POST
|
|
78
|
+
return (_a = values.POST) !== null && _a !== void 0 ? _a : null;
|
|
77
79
|
case Enums_1.HttpMethods.PATCH:
|
|
78
80
|
case Enums_1.HttpMethods.PUT:
|
|
79
|
-
return values.PUT
|
|
81
|
+
return (_b = values.PUT) !== null && _b !== void 0 ? _b : null;
|
|
80
82
|
default:
|
|
81
83
|
return null;
|
|
82
84
|
}
|
|
@@ -18,7 +18,7 @@ class GeneralHookResolver {
|
|
|
18
18
|
return __awaiter(this, void 0, void 0, function* () {
|
|
19
19
|
const fileResolver = new _1.FileResolver();
|
|
20
20
|
const content = yield fileResolver.resolveContent(this.version.folders.root);
|
|
21
|
-
if (content
|
|
21
|
+
if (content === null || content === void 0 ? void 0 : content.init) {
|
|
22
22
|
const { onBeforeInit = null, onAfterInit = null } = content.init;
|
|
23
23
|
return { onBeforeInit, onAfterInit };
|
|
24
24
|
}
|
|
@@ -11,7 +11,7 @@ class DocumentationService {
|
|
|
11
11
|
return DocumentationService.instance;
|
|
12
12
|
}
|
|
13
13
|
push(version, handler, method, url, model) {
|
|
14
|
-
var _a, _b;
|
|
14
|
+
var _a, _b, _c;
|
|
15
15
|
this.routes.push({
|
|
16
16
|
version: version.name,
|
|
17
17
|
handler,
|
|
@@ -25,7 +25,7 @@ class DocumentationService {
|
|
|
25
25
|
fillables: model.instance.getFillableFields(method),
|
|
26
26
|
validations: model.instance.getValidationRules(method),
|
|
27
27
|
queryLimits: model.queryLimits,
|
|
28
|
-
queryDefaults: ((_b = (_a = version.config) === null || _a === void 0 ? void 0 : _a.query) === null || _b === void 0 ? void 0 : _b.defaults)
|
|
28
|
+
queryDefaults: (_c = (_b = (_a = version.config) === null || _a === void 0 ? void 0 : _a.query) === null || _b === void 0 ? void 0 : _b.defaults) !== null && _c !== void 0 ? _c : {},
|
|
29
29
|
});
|
|
30
30
|
}
|
|
31
31
|
get() {
|
|
@@ -33,12 +33,10 @@ class LogService {
|
|
|
33
33
|
console.info(fgGreen, "[axe]", message, fgReset);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
log(message) {
|
|
37
|
-
if (this.level === Enums_1.LogLevels.ALL) {
|
|
38
|
-
console.log(message);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
36
|
debug(message) {
|
|
37
|
+
this.log(message);
|
|
38
|
+
}
|
|
39
|
+
log(message) {
|
|
42
40
|
if (this.level === Enums_1.LogLevels.ALL) {
|
|
43
41
|
console.log(message);
|
|
44
42
|
}
|
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { HookFunctionTypes, Extensions } from "../Enums";
|
|
2
|
-
import { IColumn,
|
|
2
|
+
import { IColumn, IModelService, IQueryLimitConfig, IRelation } from "../Interfaces";
|
|
3
3
|
import Model from "./../Model";
|
|
4
|
-
import { SerializationFunction } from "../Types";
|
|
4
|
+
import { HookFunction, SerializationFunction } from "../Types";
|
|
5
5
|
declare class ModelService implements IModelService {
|
|
6
6
|
name: string;
|
|
7
7
|
instance: Model;
|
|
8
8
|
relations: IRelation[];
|
|
9
9
|
columns: IColumn[];
|
|
10
10
|
columnNames: string[];
|
|
11
|
-
hooks: Record<HookFunctionTypes,
|
|
12
|
-
events: Record<HookFunctionTypes,
|
|
11
|
+
hooks: Record<HookFunctionTypes, HookFunction>;
|
|
12
|
+
events: Record<HookFunctionTypes, HookFunction>;
|
|
13
13
|
children: IModelService[];
|
|
14
14
|
isRecursive: boolean;
|
|
15
15
|
queryLimits: IQueryLimitConfig[];
|
|
16
16
|
serialize: SerializationFunction | null;
|
|
17
17
|
constructor(name: string, instance: Model);
|
|
18
18
|
setColumns(columns: IColumn[]): void;
|
|
19
|
-
setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data:
|
|
19
|
+
setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data: HookFunction): void;
|
|
20
20
|
setQueryLimits(limits: IQueryLimitConfig[]): void;
|
|
21
21
|
setSerialization(callback: SerializationFunction): void;
|
|
22
22
|
private setHooks;
|
|
@@ -247,10 +247,10 @@ class QueryService {
|
|
|
247
247
|
let type = Enums_1.SortTypes.ASC;
|
|
248
248
|
if (field.indexOf("-") === 0) {
|
|
249
249
|
type = Enums_1.SortTypes.DESC;
|
|
250
|
-
field = field.
|
|
250
|
+
field = field.substring(1);
|
|
251
251
|
}
|
|
252
252
|
if (field.indexOf("+") === 0) {
|
|
253
|
-
field = field.
|
|
253
|
+
field = field.substring(1);
|
|
254
254
|
}
|
|
255
255
|
this.shouldBeAcceptableColumn(field);
|
|
256
256
|
result.push({
|
|
@@ -326,14 +326,6 @@ class QueryService {
|
|
|
326
326
|
this.applySpecialCondition(where, "$between", Enums_1.ConditionTypes.Between);
|
|
327
327
|
this.applySpecialCondition(where, "$notBetween", Enums_1.ConditionTypes.NotBetween);
|
|
328
328
|
}
|
|
329
|
-
if (where.condition === Enums_1.ConditionTypes.In ||
|
|
330
|
-
where.condition === Enums_1.ConditionTypes.NotIn) {
|
|
331
|
-
where.value = where.value.split(",");
|
|
332
|
-
}
|
|
333
|
-
if (where.condition === Enums_1.ConditionTypes.Between ||
|
|
334
|
-
where.condition === Enums_1.ConditionTypes.NotBetween) {
|
|
335
|
-
where.value = where.value.split(":");
|
|
336
|
-
}
|
|
337
329
|
if (where.condition === Enums_1.ConditionTypes.LIKE ||
|
|
338
330
|
where.condition === Enums_1.ConditionTypes["NOT LIKE"]) {
|
|
339
331
|
where.value = where.value.replace(/\*/g, "%");
|
package/build/src/Types.d.ts
CHANGED
|
@@ -1,2 +1,8 @@
|
|
|
1
|
-
import { Request } from "express";
|
|
1
|
+
import { NextFunction, Request, Response } from "express";
|
|
2
|
+
import { IRequestPack, IHookParameter } from "./Interfaces";
|
|
2
3
|
export type SerializationFunction = (item: any, request: Request) => any;
|
|
4
|
+
export type HandlerFunction = (pack: IRequestPack) => void;
|
|
5
|
+
export type MiddlewareFunction = (req: Request, res: Response, next: NextFunction) => void;
|
|
6
|
+
export type ModelValidation = Record<string, string>;
|
|
7
|
+
export type FieldList = string[];
|
|
8
|
+
export type HookFunction = (pack: IHookParameter) => Promise<void>;
|
package/build/src/constants.d.ts
CHANGED
|
@@ -27,3 +27,4 @@ export declare const API_ROUTE_TEMPLATES: {
|
|
|
27
27
|
export declare const ConditionQueryFeatureMap: Record<ConditionTypes, QueryFeature>;
|
|
28
28
|
export declare const RelationQueryFeatureMap: Record<Relationships, QueryFeature>;
|
|
29
29
|
export declare const DEFAULT_VERSION_CONFIG: IVersionConfig;
|
|
30
|
+
export declare const NUMERIC_PRIMARY_KEY_TYPES: string[];
|
package/build/src/constants.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEFAULT_VERSION_CONFIG = exports.RelationQueryFeatureMap = exports.ConditionQueryFeatureMap = exports.API_ROUTE_TEMPLATES = exports.DEFAULT_METHODS_OF_MODELS = exports.DEFAULT_HANDLERS = exports.RESERVED_KEYWORDS = exports.LOG_COLORS = void 0;
|
|
3
|
+
exports.NUMERIC_PRIMARY_KEY_TYPES = exports.DEFAULT_VERSION_CONFIG = exports.RelationQueryFeatureMap = exports.ConditionQueryFeatureMap = exports.API_ROUTE_TEMPLATES = exports.DEFAULT_METHODS_OF_MODELS = exports.DEFAULT_HANDLERS = exports.RESERVED_KEYWORDS = exports.LOG_COLORS = void 0;
|
|
4
4
|
const Enums_1 = require("./Enums");
|
|
5
5
|
const LimitService_1 = require("./Services/LimitService");
|
|
6
6
|
exports.LOG_COLORS = {
|
|
@@ -115,3 +115,4 @@ exports.DEFAULT_VERSION_CONFIG = {
|
|
|
115
115
|
},
|
|
116
116
|
},
|
|
117
117
|
};
|
|
118
|
+
exports.NUMERIC_PRIMARY_KEY_TYPES = ["integer", "bigint"];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "axe-api",
|
|
3
|
-
"version": "0.31.
|
|
3
|
+
"version": "0.31.4",
|
|
4
4
|
"description": "AXE API is a simple tool which has been created based on Express and Knex.js to create Rest APIs quickly.",
|
|
5
5
|
"main": "build/index.js",
|
|
6
6
|
"types": "build/index.d.ts",
|
|
@@ -39,8 +39,11 @@
|
|
|
39
39
|
"lint:watch": "esw --watch --color",
|
|
40
40
|
"prepare:integration": "nodemon --ignore \"./tests/**\" ./scripts/run-integration-test.js",
|
|
41
41
|
"test:postgres": "sh ./scripts/test-postgres.sh",
|
|
42
|
+
"test:cockroach": "sh ./scripts/test-cockroach.sh",
|
|
42
43
|
"test:mysql57": "sh ./scripts/test-mysql57.sh",
|
|
43
44
|
"test:mysql8": "sh ./scripts/test-mysql8.sh",
|
|
45
|
+
"test:mariadb": "sh ./scripts/test-mariadb.sh",
|
|
46
|
+
"test:sqlite": "sh ./scripts/test-sqlite.sh",
|
|
44
47
|
"prettier:check": "prettier --check .",
|
|
45
48
|
"prepare": "husky install"
|
|
46
49
|
},
|
package/readme.md
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
<a href="https://badge.fury.io/js/axe-api">
|
|
10
10
|
<img src="https://badge.fury.io/js/axe-api.svg" alt="npm version" height="18">
|
|
11
11
|
</a>
|
|
12
|
-
<a href="https://github.com/axe-api/axe-api/actions/workflows/npm-publish.yml" target="_blank">
|
|
13
|
-
<img src="https://github.com/axe-api/axe-api/actions/workflows/npm-publish.yml/badge.svg?branch=master">
|
|
12
|
+
<a href="https://github.com/axe-api/axe-api/actions/workflows/npm-release-publish.yml" target="_blank">
|
|
13
|
+
<img src="https://github.com/axe-api/axe-api/actions/workflows/npm-release-publish.yml/badge.svg?branch=master">
|
|
14
14
|
</a>
|
|
15
15
|
<a href="https://sonarcloud.io/dashboard?id=axe-api_axe-api" target="_blank">
|
|
16
16
|
<img src="https://sonarcloud.io/api/project_badges/measure?project=axe-api_axe-api&metric=alert_status">
|
|
@@ -23,138 +23,24 @@
|
|
|
23
23
|
</a>
|
|
24
24
|
</h1>
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
**Axe API** is a **TypeScript-based** **Node.js** framework designed to eliminate the need for repetitive tasks associated with common elements while allowing developers to focus on custom logic.
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
It offers a comprehensive structure for your API, including numerous features and best practices that will save you time.
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Video Introduction
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
<div style="display: flex; justify-content: center;">
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
<a href="https://www.youtube.com/watch?v=3p4jggsNrJA" target="_blank">
|
|
35
|
+
<img src="./youtube.png" />
|
|
36
|
+
</a>
|
|
35
37
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
You would understand easily what you are going to code when you look at a bunch of database tables and their relations with each other, more or less. Because, as a developer, you already know that _Rest API_ best practices.
|
|
39
|
-
|
|
40
|
-
Therefore I asked a simple question more than two years ago;
|
|
41
|
-
|
|
42
|
-
**_"Can we create a Rest API in a declarative way, and handle all endpoints automatically?"_**
|
|
43
|
-
|
|
44
|
-
As a result of our work, we have a framework called Axe API that provides a solution to analyze your API definitions and handle all of the endpoints.
|
|
45
|
-
|
|
46
|
-
Basically, you define your models which are your API definitions, and Axe API analyzes them and processes all of your endpoints instead of you.
|
|
47
|
-
|
|
48
|
-
## Showcase
|
|
49
|
-
|
|
50
|
-
Let's look at an example!
|
|
51
|
-
|
|
52
|
-
You have two database tables; `users` and `posts`. These tables are related to each other and we aim that create a **Rest API** for basic **CRUD** endpoints.
|
|
53
|
-
|
|
54
|
-
The only thing to do is creating models like the following example;
|
|
55
|
-
|
|
56
|
-
```ts
|
|
57
|
-
class User extends Model {
|
|
58
|
-
get fillable(): string[] {
|
|
59
|
-
return ["email", "name", "surname"];
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
posts(): IRelation {
|
|
63
|
-
return this.hasMany("Post", "id", "user_id");
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
```ts
|
|
69
|
-
class Post extends Model {
|
|
70
|
-
get fillable(): string[] {
|
|
71
|
-
return ["title", "description"];
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
user(): IRelation {
|
|
75
|
-
return this.belongsTo("User", "user_id", "id");
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Tada! :tada:
|
|
81
|
-
|
|
82
|
-
Your API is ready to process all of the following endpoints after those model definitions are done.
|
|
83
|
-
|
|
84
|
-
- [GET] `api/users`
|
|
85
|
-
- [POST] `api/users`
|
|
86
|
-
- [GET] `api/users/:id`
|
|
87
|
-
- [PUT] `api/users/:id`
|
|
88
|
-
- [DELETE] `api/users/:id`
|
|
89
|
-
- [GET] `api/users/:userId/posts`
|
|
90
|
-
- [POST] `api/users/:userId/posts`
|
|
91
|
-
- [GET] `api/users/:userId/posts/:id`
|
|
92
|
-
- [PUT] `api/users/:userId/posts/:id`
|
|
93
|
-
- [DELETE] `api/users/:userId/posts/:id`
|
|
94
|
-
|
|
95
|
-
This is the main power of Axe API. Nevertheless, it is not limited only to this power. There are many more features are waiting to discover. :bulb:
|
|
96
|
-
|
|
97
|
-
## Installation
|
|
98
|
-
|
|
99
|
-
Using **Axe API** in an application is very easy. We've created a CLI tool for you; [axe-magic](https://github.com/axe-api/axe-magic).
|
|
100
|
-
|
|
101
|
-
You can create a new Axe API project by using [axe-magic](https://github.com/axe-api/axe-magic). But first, you can install it in your development environment. When you installed it, you can be able to access **axe-magic** command via CLI. You can use the following command to install **axe-magic** to your machine;
|
|
102
|
-
|
|
103
|
-
```bash
|
|
104
|
-
$ npm i -g axe-magic
|
|
105
|
-
$ axe-magic --version
|
|
106
|
-
1.0.0
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
After that, creating a new project is very easy. Just you can execute the following command;
|
|
110
|
-
|
|
111
|
-
```bash
|
|
112
|
-
$ axe-magic new my-api
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
This command will pull [axe-api-template](https://github.com/axe-api/axe-api-template) project to your current directory with a new name, **my-api**.
|
|
116
|
-
|
|
117
|
-
To install your project's depencies, you can execute the following commands in the root directory;
|
|
118
|
-
|
|
119
|
-
```bash
|
|
120
|
-
$ cd my-api
|
|
121
|
-
$ npm install
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
To serve this application, you can execute the following command;
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
$ npm run start:dev
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
After that, your first **Axe API** application will be running in `localhost:3000`.
|
|
131
|
-
|
|
132
|
-
You will see the following API response if you visit [localhost:3000](http://localhost:3000).
|
|
133
|
-
|
|
134
|
-
```json
|
|
135
|
-
{
|
|
136
|
-
"name": "AXE API",
|
|
137
|
-
"description": "The best API creation tool in the world."
|
|
138
|
-
}
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
If you can see that response, it means that your project is running properly.
|
|
38
|
+
</div>
|
|
142
39
|
|
|
143
40
|
## Documentation
|
|
144
41
|
|
|
145
42
|
Axe API has great documentation. Please [check it out in here](https://axe-api.com/).
|
|
146
43
|
|
|
147
|
-
## Contributors
|
|
148
|
-
|
|
149
|
-
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
150
|
-
<!-- prettier-ignore-start -->
|
|
151
|
-
<!-- markdownlint-disable -->
|
|
152
|
-
|
|
153
|
-
<!-- markdownlint-restore -->
|
|
154
|
-
<!-- prettier-ignore-end -->
|
|
155
|
-
|
|
156
|
-
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
157
|
-
|
|
158
44
|
## License
|
|
159
45
|
|
|
160
46
|
[MIT License](LICENSE)
|
package/CHANGELOG.md
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
# Release Notes
|
|
2
|
-
|
|
3
|
-
## [0.31.2 (2023-07-04)](https://github.com/axe-api/axe-api/compare/0.31.2...0.31.1)
|
|
4
|
-
|
|
5
|
-
### Fixed
|
|
6
|
-
|
|
7
|
-
- Fixed many internal issues. [#219](https://github.com/axe-api/axe-api/issues/219), [#174](https://github.com/axe-api/axe-api/issues/174), [#183](https://github.com/axe-api/axe-api/issues/183), [#149](https://github.com/axe-api/axe-api/issues/149), [#186](https://github.com/axe-api/axe-api/issues/186)
|
|
8
|
-
|
|
9
|
-
## [0.31.1 (2023-05-08)](https://github.com/axe-api/axe-api/compare/0.31.1...0.31.0)
|
|
10
|
-
|
|
11
|
-
### Fixed
|
|
12
|
-
|
|
13
|
-
- The app crashes on database errors [#155](https://github.com/axe-api/axe-api/issues/155)
|
|
14
|
-
- We should return 404 if the record is not found [#169](https://github.com/axe-api/axe-api/issues/169)
|
|
15
|
-
- An error should be thrown if the per_page value is not acceptable [#172](https://github.com/axe-api/axe-api/issues/172)
|
|
16
|
-
|
|
17
|
-
## [0.31.0 (2023-05-05)](https://github.com/axe-api/axe-api/compare/0.31.0...0.30.3)
|
|
18
|
-
|
|
19
|
-
### Features
|
|
20
|
-
|
|
21
|
-
- Added new auto-created documentation values [#179](https://github.com/axe-api/axe-api/issues/179)
|
|
22
|
-
|
|
23
|
-
### Fixed
|
|
24
|
-
|
|
25
|
-
- Fixed PostgreSQL-related issues [#204](https://github.com/axe-api/axe-api/issues/204)
|
|
26
|
-
|
|
27
|
-
## [0.30.3 (2023-05-05)](https://github.com/axe-api/axe-api/compare/0.30.3...0.30.2)
|
|
28
|
-
|
|
29
|
-
### Fixed
|
|
30
|
-
|
|
31
|
-
- Fixed security issues on dependencies.
|
|
32
|
-
|
|
33
|
-
## [0.30.2 (2023-04-18)](https://github.com/axe-api/axe-api/compare/0.30.2...0.30.1)
|
|
34
|
-
|
|
35
|
-
### Features
|
|
36
|
-
|
|
37
|
-
- Event/Hook type warning added [#163](https://github.com/axe-api/axe-api/issues/163)
|
|
38
|
-
|
|
39
|
-
## [0.30.1 (2023-04-15)](https://github.com/axe-api/axe-api/compare/0.30.1...0.30.0)
|
|
40
|
-
|
|
41
|
-
### Fixed
|
|
42
|
-
|
|
43
|
-
- Fixed URL slash character difference between windows and \*nix [#164](https://github.com/axe-api/axe-api/issues/164)
|
|
44
|
-
|
|
45
|
-
## [0.30.0 (2023-04-05)](https://github.com/axe-api/axe-api/compare/0.30.0...0.22.0)
|
|
46
|
-
|
|
47
|
-
### Breaking Changes
|
|
48
|
-
|
|
49
|
-
- Added new Serizaliation folder [#125](https://github.com/axe-api/axe-api/issues/125)
|
|
50
|
-
- New hook/event folder structure [#146](https://github.com/axe-api/axe-api/issues/146)
|
|
51
|
-
- Limiting query features by configurations [#38](https://github.com/axe-api/axe-api/issues/38)
|
|
52
|
-
- Removing external dependencies from axe-core [#151](https://github.com/axe-api/axe-api/issues/151)
|
|
53
|
-
|
|
54
|
-
## [0.22.0 (2023-01-29)](https://github.com/axe-api/axe-api/compare/0.22.0...0.21.0)
|
|
55
|
-
|
|
56
|
-
### Features
|
|
57
|
-
|
|
58
|
-
- Added Soft-Deleting feature [#41](https://github.com/axe-api/axe-api/issues/41)
|
|
59
|
-
|
|
60
|
-
### Fixed
|
|
61
|
-
|
|
62
|
-
- Fixed model relation route URLs [#141](https://github.com/axe-api/axe-api/issues/141)
|
|
63
|
-
|
|
64
|
-
## [0.21.0 (2022-12-28)](https://github.com/axe-api/axe-api/compare/0.21.0...0.20.4)
|
|
65
|
-
|
|
66
|
-
### Features
|
|
67
|
-
|
|
68
|
-
- Added `i18n` support. [#44](https://github.com/axe-api/axe-api/issues/44)
|
|
69
|
-
|
|
70
|
-
## [0.20.4 (2022-12-24)](https://github.com/axe-api/axe-api/compare/0.20.4...0.20.3)
|
|
71
|
-
|
|
72
|
-
### Fixed
|
|
73
|
-
|
|
74
|
-
- Fixed [#124](https://github.com/axe-api/axe-api/issues/124)
|
|
75
|
-
- Throwing errors in the `development` environment has been fixed.
|
|
76
|
-
- Unbuilt integration test issue has been fixed.
|
|
77
|
-
|
|
78
|
-
## [0.20.3 (2022-12-24)](https://github.com/axe-api/axe-api/compare/0.20.3...0.20.0)
|
|
79
|
-
|
|
80
|
-
### Fixed
|
|
81
|
-
|
|
82
|
-
- NPM publish bugs
|
|
83
|
-
|
|
84
|
-
## [0.20.0 (2022-12-24)](https://github.com/axe-api/axe-api/compare/0.20.0...0.19.2)
|
|
85
|
-
|
|
86
|
-
In the whole application, TypeScript becomes the new language except for migration files and it's structure. You can read the documentation about how to migrate from `0.19.2` to `0.20.0`.
|
|
87
|
-
|
|
88
|
-
### Breaking Changes
|
|
89
|
-
|
|
90
|
-
#### Naming Changes
|
|
91
|
-
|
|
92
|
-
- File extensions: `User.js` to `User.ts`
|
|
93
|
-
- `LOG_LEVELS` constant variable has been changed with `LogLevels` enum.
|
|
94
|
-
- `HANDLERS` constant variable has been changed with `HandlerTypes` enum.
|
|
95
|
-
- `IoC` service has been renamed as `IoCService`.
|
|
96
|
-
- Hooks and Event files' names should be singular;
|
|
97
|
-
- `UserHooks.js` => `UserHook.ts`
|
|
98
|
-
- `UserEvents.js` => `UserEvent.ts`
|
|
99
|
-
|
|
100
|
-
#### Interface Changes
|
|
101
|
-
|
|
102
|
-
- `validations()` getter should return `IMethodBaseValidations` interface.
|
|
103
|
-
- In hook functions, `IHookParameter` interface should be used as the parameter type.
|
|
104
|
-
- Init functions (`onBeforeInit`, `onAfterInit`) should be use the `Express` type;
|
|
105
|
-
- `const onBeforeInit = async ({ app }) => {` => `const onBeforeInit = async (app: Express) => {`
|
|
106
|
-
- `const onAfterInit = async ({ app }) => {` => `const onAfterInit = async (app: Express) => {`
|
|
107
|
-
- Application config should be implemented `IApplicationConfig` interface.
|
|
108
|
-
|
|
109
|
-
#### Implementation Changes
|
|
110
|
-
|
|
111
|
-
- Starting server part has been changed;
|
|
112
|
-
- `const server = new Server(appFolder)` => `const server = new Server()`
|
|
113
|
-
- `server.listen()` => `server.start(__dirname);`
|
|
114
|
-
- `knexfile.js` should not use the `app/Application/Config.js` anymore.
|
|
115
|
-
|
|
116
|
-
## [0.19.2 (2022-01-22)](https://github.com/axe-api/axe-api/compare/0.19.2...0.19.1)
|
|
117
|
-
|
|
118
|
-
### Fixed
|
|
119
|
-
|
|
120
|
-
- Fixed the calling `onBeforePaginate` and `onBeforeShow` hooks bug.
|
|
121
|
-
|
|
122
|
-
## [0.19.1 (2022-01-22)](https://github.com/axe-api/axe-api/compare/0.19.1...0.19.0)
|
|
123
|
-
|
|
124
|
-
### Fixed
|
|
125
|
-
|
|
126
|
-
- knex.js version update.
|
|
127
|
-
|
|
128
|
-
## [0.19.0 (2021-12-05)](https://github.com/axe-api/axe-api/compare/0.19.0...0.18.1)
|
|
129
|
-
|
|
130
|
-
### Fixed
|
|
131
|
-
|
|
132
|
-
- [#110](https://github.com/axe-api/axe-api/issues/110)
|
|
133
|
-
|
|
134
|
-
### Enhancements
|
|
135
|
-
|
|
136
|
-
- [#106](https://github.com/axe-api/axe-api/issues/106)
|
|
137
|
-
|
|
138
|
-
## [0.18.1 (2021-12-02)](https://github.com/axe-api/axe-api/compare/0.18.1...0.18.0)
|
|
139
|
-
|
|
140
|
-
### Fixed
|
|
141
|
-
|
|
142
|
-
- [#117](https://github.com/axe-api/axe-api/issues/117)
|
|
143
|
-
|
|
144
|
-
## [0.18.0 (2021-11-30)](https://github.com/axe-api/axe-api/compare/0.18.0...0.17.5)
|
|
145
|
-
|
|
146
|
-
### Fixed
|
|
147
|
-
|
|
148
|
-
- [#115](https://github.com/axe-api/axe-api/issues/115)
|
|
149
|
-
- [#114](https://github.com/axe-api/axe-api/issues/114)
|
|
150
|
-
|
|
151
|
-
### Enhancements
|
|
152
|
-
|
|
153
|
-
- [#113](https://github.com/axe-api/axe-api/issues/113)
|
|
154
|
-
- [#107](https://github.com/axe-api/axe-api/issues/107)
|
|
155
|
-
- [#108](https://github.com/axe-api/axe-api/issues/108)
|
|
156
|
-
|
|
157
|
-
## [0.17.5 (2021-11-27)](https://github.com/axe-api/axe-api/compare/0.17.5...0.17.4)
|
|
158
|
-
|
|
159
|
-
### Fixed
|
|
160
|
-
|
|
161
|
-
- [#111](https://github.com/axe-api/axe-api/issues/111)
|
|
162
|
-
|
|
163
|
-
## [0.17.4 (2021-10-28)](https://github.com/axe-api/axe-api/compare/0.17.4...0.17.3)
|
|
164
|
-
|
|
165
|
-
### Fixed
|
|
166
|
-
|
|
167
|
-
- [#97](https://github.com/axe-api/axe-api/issues/97)
|
|
168
|
-
- [#104](https://github.com/axe-api/axe-api/issues/104)
|
|
169
|
-
|
|
170
|
-
## [0.17.3 (2021-10-28)](https://github.com/axe-api/axe-api/compare/0.17.3...0.17.2)
|
|
171
|
-
|
|
172
|
-
### Fixed
|
|
173
|
-
|
|
174
|
-
- [#98](https://github.com/axe-api/axe-api/issues/98)
|
|
175
|
-
|
|
176
|
-
## [0.17.2 (2021-10-17)](https://github.com/axe-api/axe-api/compare/0.17.2...0.17.1)
|
|
177
|
-
|
|
178
|
-
### Fixed
|
|
179
|
-
|
|
180
|
-
- Fixed table join on the related table filter.
|
|
181
|
-
|
|
182
|
-
## [0.17.1 (2021-10-17)](https://github.com/axe-api/axe-api/compare/0.17.1...0.17.0)
|
|
183
|
-
|
|
184
|
-
### Fixed
|
|
185
|
-
|
|
186
|
-
- Query bug on child models [#93](https://github.com/axe-api/axe-api/issues/93)
|
|
187
|
-
|
|
188
|
-
## [0.17.0 (2021-10-17)](https://github.com/axe-api/axe-api/compare/0.17.0...0.16.0)
|
|
189
|
-
|
|
190
|
-
### Fixed
|
|
191
|
-
|
|
192
|
-
- Related query column name check bug has been fixed.
|
|
193
|
-
|
|
194
|
-
### Features
|
|
195
|
-
|
|
196
|
-
- Global serializer for HTTP results [#37](https://github.com/axe-api/axe-api/issues/37)
|
|
197
|
-
|
|
198
|
-
## [0.16.0 (2021-10-06)](https://github.com/axe-api/axe-api/compare/0.16.0...0.15.0)
|
|
199
|
-
|
|
200
|
-
### Features
|
|
201
|
-
|
|
202
|
-
- Fixes [#89](https://github.com/axe-api/axe-api/issues/89)
|
|
203
|
-
|
|
204
|
-
## [0.15.0 (2021-10-03)](https://github.com/axe-api/axe-api/compare/0.15.0...0.14.1)
|
|
205
|
-
|
|
206
|
-
### Features
|
|
207
|
-
|
|
208
|
-
- Fixes [#87](https://github.com/axe-api/axe-api/issues/87)
|
|
209
|
-
|
|
210
|
-
## [0.14.1 (2021-09-20)](https://github.com/axe-api/axe-api/compare/0.14.1...0.14.0)
|
|
211
|
-
|
|
212
|
-
### Fixed
|
|
213
|
-
|
|
214
|
-
- Fixes [#83](https://github.com/axe-api/axe-api/issues/83)
|
|
215
|
-
|
|
216
|
-
## [0.14.0 (2021-09-15)](https://github.com/axe-api/axe-api/compare/0.14.0...0.13.3)
|
|
217
|
-
|
|
218
|
-
### Features
|
|
219
|
-
|
|
220
|
-
- General hooks definition feature has been added. ([#81](https://github.com/axe-api/axe-api/issues/81))
|
|
221
|
-
|
|
222
|
-
## [0.13.3 (2021-09-15)](https://github.com/axe-api/axe-api/compare/0.13.2...0.13.3)
|
|
223
|
-
|
|
224
|
-
### Fixed
|
|
225
|
-
|
|
226
|
-
- Fixed CORS bugs.
|
|
227
|
-
|
|
228
|
-
## [0.13.2 (2021-08-20)](https://github.com/axe-api/axe-api/compare/0.13.1...0.13.2)
|
|
229
|
-
|
|
230
|
-
### Fixed
|
|
231
|
-
|
|
232
|
-
- Fixes [#27](https://github.com/axe-api/axe-api/issues/27)
|
|
233
|
-
- Fixes [#29](https://github.com/axe-api/axe-api/issues/29)
|
|
234
|
-
- Fixes [#75](https://github.com/axe-api/axe-api/issues/75)
|
|
235
|
-
- Fixes [#78](https://github.com/axe-api/axe-api/issues/78)
|
|
236
|
-
|
|
237
|
-
## [0.13.1 (2021-08-09)](https://github.com/axe-api/axe-api/compare/0.13.0...0.13.1)
|
|
238
|
-
|
|
239
|
-
### Fixed
|
|
240
|
-
|
|
241
|
-
- Fixes [#69](https://github.com/axe-api/axe-api/issues/69)
|
|
242
|
-
- Fixes [#70](https://github.com/axe-api/axe-api/issues/70)
|
|
243
|
-
- Fixes [#71](https://github.com/axe-api/axe-api/issues/71)
|
|
244
|
-
- Fixes [#72](https://github.com/axe-api/axe-api/issues/72)
|
|
245
|
-
|
|
246
|
-
## [0.13.0 (2021-07-25)](https://github.com/axe-api/axe-api/compare/0.12.2...0.13.0)
|
|
247
|
-
|
|
248
|
-
### Features
|
|
249
|
-
|
|
250
|
-
- PostgreSQL database analyzer and integration tests have been added.
|
|
251
|
-
|
|
252
|
-
## [0.12.2 (2021-07-24)](https://github.com/axe-api/axe-api/compare/0.12.1...0.12.2)
|
|
253
|
-
|
|
254
|
-
### Fixed
|
|
255
|
-
|
|
256
|
-
- Throwing an error if the primary key column isn't in the database table bug has been fixed. (#61)[https://github.com/axe-api/axe-api/issues/61]
|
|
257
|
-
- Using numeric column name bug has been fixed. (#24)[https://github.com/axe-api/axe-api/issues/24]
|
|
258
|
-
|
|
259
|
-
## [0.12.1 (2021-07-24)](https://github.com/axe-api/axe-api/compare/0.12.0...0.12.1)
|
|
260
|
-
|
|
261
|
-
### Fixed
|
|
262
|
-
|
|
263
|
-
- Fixed security issues.
|