axe-api 0.31.1 → 0.31.3

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.
@@ -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.substr(0, 1) === "/") {
36
- prefix = prefix.substr(1);
35
+ if (prefix.startsWith("/")) {
36
+ prefix = prefix.substring(1);
37
37
  }
38
- if (prefix.substr(prefix.length - 1) === "/") {
39
- prefix = prefix.substr(0, prefix.length - 1);
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
- switch (type) {
214
- case "ApiError":
215
- // eslint-disable-next-line no-case-declarations
216
- const apiError = error;
217
- res.status(apiError.status).json({
218
- error: apiError.message,
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}.`, Enums_2.StatusCodes.NOT_FOUND);
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 }));
@@ -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.", Enums_2.StatusCodes.NOT_FOUND);
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);
@@ -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): (pack: IRequestPack) => void;
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>, columnTypes: TimestampColumns[] | undefined, model: IModelService) => void;
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[] | any, modelSerializer: SerializationFunction | null, handler: HandlerTypes, request: Request) => Promise<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 = [], model) => {
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
- yield model.hooks[type](params);
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
@@ -117,7 +118,6 @@ const globalSerializer = (version, itemArray, handler, request) => __awaiter(voi
117
118
  // Serialize data with specific handler like "PAGINATE" or "SHOW".
118
119
  if (configSerializer.handler.includes(handler)) {
119
120
  callbacks.push(...configSerializer.serializer);
120
- return;
121
121
  }
122
122
  });
123
123
  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}.`, Enums_2.StatusCodes.NOT_FOUND);
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], model);
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}.`, Enums_2.StatusCodes.NOT_FOUND);
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, [Enums_1.TimestampColumns.CREATED_AT, Enums_1.TimestampColumns.UPDATED_AT], model);
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}.`, Enums_2.StatusCodes.NOT_FOUND);
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], model);
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 | null;
100
- item: any | null;
101
- formData: any | null;
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, (params: IHookParameter) => void>;
119
- events: Record<HookFunctionTypes, (params: IHookParameter) => void>;
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: (params: IHookParameter) => void): void;
125
+ setExtensions(type: Extensions, hookFunctionType: HookFunctionTypes, data: HookFunction): void;
126
126
  setQueryLimits(limits: IQueryLimitConfig[]): void;
127
127
  setSerialization(callback: SerializationFunction): void;
128
128
  }
@@ -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(): string[] | IMethodBaseConfig;
8
- get validations(): IMethodBaseValidations | Record<string, string>;
7
+ get fillable(): FieldList | IMethodBaseConfig;
8
+ get validations(): IMethodBaseValidations | ModelValidation;
9
9
  get handlers(): HandlerTypes[];
10
- get middlewares(): ((req: Request, res: Response, next: NextFunction) => void)[] | IHandlerBaseMiddleware[] | IHandlerBaseMiddleware;
11
- get hiddens(): string[];
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): Record<string, string> | null;
20
- getMiddlewares(handlerType: HandlerTypes): ((req: Request, res: Response, next: NextFunction) => void)[];
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;
@@ -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 || null;
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 || null;
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 && content.init) {
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() {
@@ -9,7 +9,7 @@ declare class LogService {
9
9
  warn(message: string): void;
10
10
  info(message: string): void;
11
11
  success(message: string): void;
12
- log(message: string): void;
13
12
  debug(message: string): void;
13
+ log(message: string): void;
14
14
  }
15
15
  export default LogService;
@@ -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, IHookParameter, IModelService, IQueryLimitConfig, IRelation } from "../Interfaces";
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, (params: IHookParameter) => void>;
12
- events: Record<HookFunctionTypes, (params: IHookParameter) => void>;
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: (params: IHookParameter) => void): void;
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.substr(1);
250
+ field = field.substring(1);
251
251
  }
252
252
  if (field.indexOf("+") === 0) {
253
- field = field.substr(1);
253
+ field = field.substring(1);
254
254
  }
255
255
  this.shouldBeAcceptableColumn(field);
256
256
  result.push({
@@ -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>;
@@ -24,6 +24,7 @@ exports.RESERVED_KEYWORDS = [
24
24
  "hooks",
25
25
  "event",
26
26
  "events",
27
+ "all",
27
28
  ];
28
29
  exports.DEFAULT_HANDLERS = [
29
30
  Enums_1.HandlerTypes.INSERT,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "axe-api",
3
- "version": "0.31.1",
3
+ "version": "0.31.3",
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",
@@ -35,19 +35,21 @@
35
35
  "dev-kit:remove": "node ./scripts/dev-kit-remove.js",
36
36
  "test": "jest --runInBand",
37
37
  "test:dev": "jest --watch",
38
- "lint": "eslint src/**",
38
+ "lint": "eslint --max-warnings=0 .",
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
42
  "test:mysql57": "sh ./scripts/test-mysql57.sh",
43
- "test:mysql8": "sh ./scripts/test-mysql8.sh"
43
+ "test:mysql8": "sh ./scripts/test-mysql8.sh",
44
+ "prettier:check": "prettier --check .",
45
+ "prepare": "husky install"
44
46
  },
45
47
  "dependencies": {
46
48
  "chalk": "^4.1.2",
47
49
  "change-case": "^4.1.2",
48
- "dotenv": "^16.0.3",
50
+ "dotenv": "^16.3.1",
49
51
  "knex": "^2.4.2",
50
- "knex-paginate": "^3.1.0",
52
+ "knex-paginate": "^3.1.1",
51
53
  "knex-schema-inspector": "^3.0.1",
52
54
  "pluralize": "^8.0.0",
53
55
  "validatorjs": "^3.22.1"
@@ -61,8 +63,8 @@
61
63
  "@types/multer": "^1.4.7",
62
64
  "@types/pluralize": "^0.0.29",
63
65
  "@types/validatorjs": "^3.15.0",
64
- "@typescript-eslint/eslint-plugin": "^5.56.0",
65
- "@typescript-eslint/parser": "^5.56.0",
66
+ "@typescript-eslint/eslint-plugin": "^5.61.0",
67
+ "@typescript-eslint/parser": "^5.61.0",
66
68
  "babel-jest": "^29.5.0",
67
69
  "eslint": "^7.32.0",
68
70
  "eslint-config-standard": "^16.0.3",
@@ -73,7 +75,9 @@
73
75
  "eslint-watch": "^7.0.0",
74
76
  "express": "^4.18.2",
75
77
  "glob": "^9.3.2",
78
+ "husky": "^8.0.3",
76
79
  "jest": "^29.5.0",
80
+ "lint-staged": "^13.2.3",
77
81
  "multer": "^1.4.5-lts.1",
78
82
  "mysql": "^2.18.1",
79
83
  "node-color-log": "^10.0.2",
@@ -84,5 +88,8 @@
84
88
  "sqlite3": "^5.1.6",
85
89
  "ts-node": "^10.9.1",
86
90
  "typescript": "^5.0.2"
91
+ },
92
+ "lint-staged": {
93
+ "**/*": "prettier --write --ignore-unknown"
87
94
  }
88
95
  }
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,123 +23,19 @@
23
23
  </a>
24
24
  </h1>
25
25
 
26
- Next Generation Rest API Framework
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
- > Axe API has great documentation. Please [check it out in here](https://axe-api.com/).
28
+ It offers a comprehensive structure for your API, including numerous features and best practices that will save you time.
29
29
 
30
- ## What Is Axe API?
30
+ ## Video Introduction
31
31
 
32
- Axe API is a [Node.js](https://nodejs.org/) framework that helps you create a **Rest API** in a declarative way quickly. :axe:
32
+ <div style="display: flex; justify-content: center;">
33
33
 
34
- It has been written with [TypeScript](https://www.typescriptlang.org/) and built on [Express](https://expressjs.com/) and [Knex.js](https://knexjs.org/).
34
+ <a href="https://www.youtube.com/watch?v=3p4jggsNrJA" target="_blank">
35
+ <img src="./youtube.png" />
36
+ </a>
35
37
 
36
- ## Motivation
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
- "aim": "To kill them all!"
139
- }
140
- ```
141
-
142
- If you can see that response, it means that your project is running properly.
38
+ </div>
143
39
 
144
40
  ## Documentation
145
41
 
package/CHANGELOG.md DELETED
@@ -1,257 +0,0 @@
1
- # Release Notes
2
-
3
- ## [0.31.1 (2023-05-08)](https://github.com/axe-api/axe-api/compare/0.31.1...0.31.0)
4
-
5
- ### Fixed
6
-
7
- - The app crashes on database errors [#155](https://github.com/axe-api/axe-api/issues/155)
8
- - We should return 404 if the record is not found [#169](https://github.com/axe-api/axe-api/issues/169)
9
- - An error should be thrown if the per_page value is not acceptable [#172](https://github.com/axe-api/axe-api/issues/172)
10
-
11
- ## [0.31.0 (2023-05-05)](https://github.com/axe-api/axe-api/compare/0.31.0...0.30.3)
12
-
13
- ### Features
14
-
15
- - Added new auto-created documentation values [#179](https://github.com/axe-api/axe-api/issues/179)
16
-
17
- ### Fixed
18
-
19
- - Fixed PostgreSQL-related issues [#204](https://github.com/axe-api/axe-api/issues/204)
20
-
21
- ## [0.30.3 (2023-05-05)](https://github.com/axe-api/axe-api/compare/0.30.3...0.30.2)
22
-
23
- ### Fixed
24
-
25
- - Fixed security issues on dependencies.
26
-
27
- ## [0.30.2 (2023-04-18)](https://github.com/axe-api/axe-api/compare/0.30.2...0.30.1)
28
-
29
- ### Features
30
-
31
- - Event/Hook type warning added [#163](https://github.com/axe-api/axe-api/issues/163)
32
-
33
- ## [0.30.1 (2023-04-15)](https://github.com/axe-api/axe-api/compare/0.30.1...0.30.0)
34
-
35
- ### Fixed
36
-
37
- - Fixed URL slash character difference between windows and \*nix [#164](https://github.com/axe-api/axe-api/issues/164)
38
-
39
- ## [0.30.0 (2023-04-05)](https://github.com/axe-api/axe-api/compare/0.30.0...0.22.0)
40
-
41
- ### Breaking Changes
42
-
43
- - Added new Serizaliation folder [#125](https://github.com/axe-api/axe-api/issues/125)
44
- - New hook/event folder structure [#146](https://github.com/axe-api/axe-api/issues/146)
45
- - Limiting query features by configurations [#38](https://github.com/axe-api/axe-api/issues/38)
46
- - Removing external dependencies from axe-core [#151](https://github.com/axe-api/axe-api/issues/151)
47
-
48
- ## [0.22.0 (2023-01-29)](https://github.com/axe-api/axe-api/compare/0.22.0...0.21.0)
49
-
50
- ### Features
51
-
52
- - Added Soft-Deleting feature [#41](https://github.com/axe-api/axe-api/issues/41)
53
-
54
- ### Fixed
55
-
56
- - Fixed model relation route URLs [#141](https://github.com/axe-api/axe-api/issues/141)
57
-
58
- ## [0.21.0 (2022-12-28)](https://github.com/axe-api/axe-api/compare/0.21.0...0.20.4)
59
-
60
- ### Features
61
-
62
- - Added `i18n` support. [#44](https://github.com/axe-api/axe-api/issues/44)
63
-
64
- ## [0.20.4 (2022-12-24)](https://github.com/axe-api/axe-api/compare/0.20.4...0.20.3)
65
-
66
- ### Fixed
67
-
68
- - Fixed [#124](https://github.com/axe-api/axe-api/issues/124)
69
- - Throwing errors in the `development` environment has been fixed.
70
- - Unbuilt integration test issue has been fixed.
71
-
72
- ## [0.20.3 (2022-12-24)](https://github.com/axe-api/axe-api/compare/0.20.3...0.20.0)
73
-
74
- ### Fixed
75
-
76
- - NPM publish bugs
77
-
78
- ## [0.20.0 (2022-12-24)](https://github.com/axe-api/axe-api/compare/0.20.0...0.19.2)
79
-
80
- 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`.
81
-
82
- ### Breaking Changes
83
-
84
- #### Naming Changes
85
-
86
- - File extensions: `User.js` to `User.ts`
87
- - `LOG_LEVELS` constant variable has been changed with `LogLevels` enum.
88
- - `HANDLERS` constant variable has been changed with `HandlerTypes` enum.
89
- - `IoC` service has been renamed as `IoCService`.
90
- - Hooks and Event files' names should be singular;
91
- - `UserHooks.js` => `UserHook.ts`
92
- - `UserEvents.js` => `UserEvent.ts`
93
-
94
- #### Interface Changes
95
-
96
- - `validations()` getter should return `IMethodBaseValidations` interface.
97
- - In hook functions, `IHookParameter` interface should be used as the parameter type.
98
- - Init functions (`onBeforeInit`, `onAfterInit`) should be use the `Express` type;
99
- - `const onBeforeInit = async ({ app }) => {` => `const onBeforeInit = async (app: Express) => {`
100
- - `const onAfterInit = async ({ app }) => {` => `const onAfterInit = async (app: Express) => {`
101
- - Application config should be implemented `IApplicationConfig` interface.
102
-
103
- #### Implementation Changes
104
-
105
- - Starting server part has been changed;
106
- - `const server = new Server(appFolder)` => `const server = new Server()`
107
- - `server.listen()` => `server.start(__dirname);`
108
- - `knexfile.js` should not use the `app/Application/Config.js` anymore.
109
-
110
- ## [0.19.2 (2022-01-22)](https://github.com/axe-api/axe-api/compare/0.19.2...0.19.1)
111
-
112
- ### Fixed
113
-
114
- - Fixed the calling `onBeforePaginate` and `onBeforeShow` hooks bug.
115
-
116
- ## [0.19.1 (2022-01-22)](https://github.com/axe-api/axe-api/compare/0.19.1...0.19.0)
117
-
118
- ### Fixed
119
-
120
- - knex.js version update.
121
-
122
- ## [0.19.0 (2021-12-05)](https://github.com/axe-api/axe-api/compare/0.19.0...0.18.1)
123
-
124
- ### Fixed
125
-
126
- - [#110](https://github.com/axe-api/axe-api/issues/110)
127
-
128
- ### Enhancements
129
-
130
- - [#106](https://github.com/axe-api/axe-api/issues/106)
131
-
132
- ## [0.18.1 (2021-12-02)](https://github.com/axe-api/axe-api/compare/0.18.1...0.18.0)
133
-
134
- ### Fixed
135
-
136
- - [#117](https://github.com/axe-api/axe-api/issues/117)
137
-
138
- ## [0.18.0 (2021-11-30)](https://github.com/axe-api/axe-api/compare/0.18.0...0.17.5)
139
-
140
- ### Fixed
141
-
142
- - [#115](https://github.com/axe-api/axe-api/issues/115)
143
- - [#114](https://github.com/axe-api/axe-api/issues/114)
144
-
145
- ### Enhancements
146
-
147
- - [#113](https://github.com/axe-api/axe-api/issues/113)
148
- - [#107](https://github.com/axe-api/axe-api/issues/107)
149
- - [#108](https://github.com/axe-api/axe-api/issues/108)
150
-
151
- ## [0.17.5 (2021-11-27)](https://github.com/axe-api/axe-api/compare/0.17.5...0.17.4)
152
-
153
- ### Fixed
154
-
155
- - [#111](https://github.com/axe-api/axe-api/issues/111)
156
-
157
- ## [0.17.4 (2021-10-28)](https://github.com/axe-api/axe-api/compare/0.17.4...0.17.3)
158
-
159
- ### Fixed
160
-
161
- - [#97](https://github.com/axe-api/axe-api/issues/97)
162
- - [#104](https://github.com/axe-api/axe-api/issues/104)
163
-
164
- ## [0.17.3 (2021-10-28)](https://github.com/axe-api/axe-api/compare/0.17.3...0.17.2)
165
-
166
- ### Fixed
167
-
168
- - [#98](https://github.com/axe-api/axe-api/issues/98)
169
-
170
- ## [0.17.2 (2021-10-17)](https://github.com/axe-api/axe-api/compare/0.17.2...0.17.1)
171
-
172
- ### Fixed
173
-
174
- - Fixed table join on the related table filter.
175
-
176
- ## [0.17.1 (2021-10-17)](https://github.com/axe-api/axe-api/compare/0.17.1...0.17.0)
177
-
178
- ### Fixed
179
-
180
- - Query bug on child models [#93](https://github.com/axe-api/axe-api/issues/93)
181
-
182
- ## [0.17.0 (2021-10-17)](https://github.com/axe-api/axe-api/compare/0.17.0...0.16.0)
183
-
184
- ### Fixed
185
-
186
- - Related query column name check bug has been fixed.
187
-
188
- ### Features
189
-
190
- - Global serializer for HTTP results [#37](https://github.com/axe-api/axe-api/issues/37)
191
-
192
- ## [0.16.0 (2021-10-06)](https://github.com/axe-api/axe-api/compare/0.16.0...0.15.0)
193
-
194
- ### Features
195
-
196
- - Fixes [#89](https://github.com/axe-api/axe-api/issues/89)
197
-
198
- ## [0.15.0 (2021-10-03)](https://github.com/axe-api/axe-api/compare/0.15.0...0.14.1)
199
-
200
- ### Features
201
-
202
- - Fixes [#87](https://github.com/axe-api/axe-api/issues/87)
203
-
204
- ## [0.14.1 (2021-09-20)](https://github.com/axe-api/axe-api/compare/0.14.1...0.14.0)
205
-
206
- ### Fixed
207
-
208
- - Fixes [#83](https://github.com/axe-api/axe-api/issues/83)
209
-
210
- ## [0.14.0 (2021-09-15)](https://github.com/axe-api/axe-api/compare/0.14.0...0.13.3)
211
-
212
- ### Features
213
-
214
- - General hooks definition feature has been added. ([#81](https://github.com/axe-api/axe-api/issues/81))
215
-
216
- ## [0.13.3 (2021-09-15)](https://github.com/axe-api/axe-api/compare/0.13.2...0.13.3)
217
-
218
- ### Fixed
219
-
220
- - Fixed CORS bugs.
221
-
222
- ## [0.13.2 (2021-08-20)](https://github.com/axe-api/axe-api/compare/0.13.1...0.13.2)
223
-
224
- ### Fixed
225
-
226
- - Fixes [#27](https://github.com/axe-api/axe-api/issues/27)
227
- - Fixes [#29](https://github.com/axe-api/axe-api/issues/29)
228
- - Fixes [#75](https://github.com/axe-api/axe-api/issues/75)
229
- - Fixes [#78](https://github.com/axe-api/axe-api/issues/78)
230
-
231
- ## [0.13.1 (2021-08-09)](https://github.com/axe-api/axe-api/compare/0.13.0...0.13.1)
232
-
233
- ### Fixed
234
-
235
- - Fixes [#69](https://github.com/axe-api/axe-api/issues/69)
236
- - Fixes [#70](https://github.com/axe-api/axe-api/issues/70)
237
- - Fixes [#71](https://github.com/axe-api/axe-api/issues/71)
238
- - Fixes [#72](https://github.com/axe-api/axe-api/issues/72)
239
-
240
- ## [0.13.0 (2021-07-25)](https://github.com/axe-api/axe-api/compare/0.12.2...0.13.0)
241
-
242
- ### Features
243
-
244
- - PostgreSQL database analyzer and integration tests have been added.
245
-
246
- ## [0.12.2 (2021-07-24)](https://github.com/axe-api/axe-api/compare/0.12.1...0.12.2)
247
-
248
- ### Fixed
249
-
250
- - 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]
251
- - Using numeric column name bug has been fixed. (#24)[https://github.com/axe-api/axe-api/issues/24]
252
-
253
- ## [0.12.1 (2021-07-24)](https://github.com/axe-api/axe-api/compare/0.12.0...0.12.1)
254
-
255
- ### Fixed
256
-
257
- - Fixed security issues.