axe-api 0.19.1 → 0.20.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/index.d.ts +8 -0
- package/build/index.js +32 -0
- package/build/src/Builders/ModelTreeBuilder.d.ts +9 -0
- package/build/src/Builders/ModelTreeBuilder.js +64 -0
- package/build/src/Builders/RouterBuilder.d.ts +15 -0
- package/build/src/Builders/RouterBuilder.js +219 -0
- package/build/src/Builders/index.d.ts +3 -0
- package/build/src/Builders/index.js +10 -0
- package/build/src/Enums.d.ts +77 -0
- package/build/src/Enums.js +90 -0
- package/build/src/Exceptions/ApiError.d.ts +8 -0
- package/build/src/Exceptions/ApiError.js +12 -0
- package/build/src/Handlers/AllHandler.d.ts +4 -0
- package/build/src/Handlers/AllHandler.js +44 -0
- package/build/src/Handlers/DestroyHandler.d.ts +4 -0
- package/build/src/Handlers/DestroyHandler.js +37 -0
- package/build/src/Handlers/HandlerFactory.d.ts +6 -0
- package/build/src/Handlers/HandlerFactory.js +36 -0
- package/build/src/Handlers/Helpers.d.ts +14 -0
- package/build/src/Handlers/Helpers.js +231 -0
- package/build/src/Handlers/PaginateHandler.d.ts +4 -0
- package/build/src/Handlers/PaginateHandler.js +48 -0
- package/build/src/Handlers/PatchHandler.d.ts +4 -0
- package/build/src/Handlers/PatchHandler.js +62 -0
- package/build/src/Handlers/ShowHandler.d.ts +4 -0
- package/build/src/Handlers/ShowHandler.js +51 -0
- package/build/src/Handlers/StoreHandler.d.ts +4 -0
- package/build/src/Handlers/StoreHandler.js +59 -0
- package/build/src/Handlers/UpdateHandler.d.ts +4 -0
- package/build/src/Handlers/UpdateHandler.js +62 -0
- package/build/src/Interfaces.d.ts +165 -0
- package/build/src/Interfaces.js +3 -0
- package/build/src/Model.d.ts +24 -0
- package/build/src/Model.js +108 -0
- package/build/src/Resolvers/FileResolver.d.ts +5 -0
- package/build/src/Resolvers/FileResolver.js +76 -0
- package/build/src/Resolvers/FolderResolver.d.ts +5 -0
- package/build/src/Resolvers/FolderResolver.js +19 -0
- package/build/src/Resolvers/GeneralHookResolver.d.ts +5 -0
- package/build/src/Resolvers/GeneralHookResolver.js +35 -0
- package/build/src/Resolvers/ModelMiddlewareResolver.d.ts +7 -0
- package/build/src/Resolvers/ModelMiddlewareResolver.js +29 -0
- package/build/src/Resolvers/ModelResolver.d.ts +9 -0
- package/build/src/Resolvers/ModelResolver.js +101 -0
- package/build/src/Resolvers/TransactionResolver.d.ts +8 -0
- package/build/src/Resolvers/TransactionResolver.js +75 -0
- package/build/src/Resolvers/index.d.ts +7 -0
- package/build/src/Resolvers/index.js +18 -0
- package/build/src/Server.d.ts +8 -0
- package/build/src/Server.js +101 -0
- package/build/src/Services/DocumentationService.d.ts +9 -0
- package/build/src/Services/DocumentationService.js +22 -0
- package/build/src/Services/IoCService.d.ts +9 -0
- package/build/src/Services/IoCService.js +51 -0
- package/build/src/Services/LogService.d.ts +12 -0
- package/build/src/Services/LogService.js +41 -0
- package/build/src/Services/ModelListService.d.ts +8 -0
- package/build/src/Services/ModelListService.js +18 -0
- package/build/src/Services/ModelService.d.ts +20 -0
- package/build/src/Services/ModelService.js +38 -0
- package/build/src/Services/QueryService.d.ts +39 -0
- package/build/src/Services/QueryService.js +447 -0
- package/build/src/Services/SchemaValidatorService.d.ts +12 -0
- package/build/src/Services/SchemaValidatorService.js +114 -0
- package/build/src/Services/index.d.ts +8 -0
- package/build/src/Services/index.js +20 -0
- package/build/src/constants.d.ts +23 -0
- package/build/src/constants.js +62 -0
- package/package.json +65 -56
- package/readme.md +152 -145
- package/.eslintrc.cjs +0 -24
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -32
- package/.github/workflows/auto-tag.yml +0 -15
- package/.github/workflows/npm-publish.yml +0 -18
- package/.github/workflows/test-integration.yml +0 -29
- package/.github/workflows/test-unit.yml +0 -23
- package/CHANGELOG.md +0 -144
- package/babel.config.cjs +0 -12
- package/index.js +0 -21
- package/jest.config.js +0 -4
- package/src/Server.js +0 -118
- package/src/constants.js +0 -148
- package/src/core/Config.js +0 -38
- package/src/core/Docs.js +0 -43
- package/src/core/HttpResponse.js +0 -10
- package/src/core/IoC.js +0 -41
- package/src/core/Logger.js +0 -46
- package/src/core/Model.js +0 -86
- package/src/core/QueryParser.js +0 -544
- package/src/handlers/all.js +0 -73
- package/src/handlers/destroy.js +0 -50
- package/src/handlers/helpers.js +0 -320
- package/src/handlers/index.js +0 -9
- package/src/handlers/paginate.js +0 -77
- package/src/handlers/patch.js +0 -95
- package/src/handlers/show.js +0 -81
- package/src/handlers/store.js +0 -82
- package/src/handlers/update.js +0 -92
- package/src/resolvers/checkModelColumns.js +0 -113
- package/src/resolvers/detectDbColumns.js +0 -42
- package/src/resolvers/getModelInstanceArray.js +0 -27
- package/src/resolvers/getModelTree.js +0 -63
- package/src/resolvers/index.js +0 -17
- package/src/resolvers/setExpressRoutes.js +0 -286
- package/src/resolvers/setModelHooks.js +0 -25
- package/src/resolvers/setModelRelations.js +0 -41
package/src/handlers/destroy.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { callHooks, addForeignKeyQuery } from "./helpers.js";
|
|
2
|
-
import { HOOK_FUNCTIONS } from "./../constants.js";
|
|
3
|
-
import HttpResponse from "./../core/HttpResponse.js";
|
|
4
|
-
|
|
5
|
-
export default async (context) => {
|
|
6
|
-
const { request, response, model, trx, relation, parentModel } = context;
|
|
7
|
-
|
|
8
|
-
const query = trx
|
|
9
|
-
.from(model.instance.table)
|
|
10
|
-
.where(
|
|
11
|
-
model.instance.primaryKey,
|
|
12
|
-
request.params[model.instance.primaryKey]
|
|
13
|
-
);
|
|
14
|
-
|
|
15
|
-
// If there is a relation, we should bind it
|
|
16
|
-
addForeignKeyQuery(request, query, relation, parentModel);
|
|
17
|
-
|
|
18
|
-
await callHooks(model, HOOK_FUNCTIONS.onBeforeDeleteQuery, {
|
|
19
|
-
...context,
|
|
20
|
-
query,
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
let item = await query.first();
|
|
24
|
-
if (!item) {
|
|
25
|
-
throw new HttpResponse(404, {
|
|
26
|
-
message: `The item is not found on ${model.name}.`,
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
await callHooks(model, HOOK_FUNCTIONS.onAfterDeleteQuery, {
|
|
31
|
-
...context,
|
|
32
|
-
query,
|
|
33
|
-
item,
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
await callHooks(model, HOOK_FUNCTIONS.onBeforeDelete, {
|
|
37
|
-
...context,
|
|
38
|
-
query,
|
|
39
|
-
item,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
await query.delete();
|
|
43
|
-
|
|
44
|
-
await callHooks(model, HOOK_FUNCTIONS.onAfterDelete, {
|
|
45
|
-
...context,
|
|
46
|
-
item,
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
return response.json();
|
|
50
|
-
};
|
package/src/handlers/helpers.js
DELETED
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
import { RELATIONSHIPS } from "./../constants.js";
|
|
2
|
-
import { camelCase } from "change-case";
|
|
3
|
-
import HttpResponse from "./../core/HttpResponse.js";
|
|
4
|
-
import IoC from "../core/IoC.js";
|
|
5
|
-
|
|
6
|
-
const getInputFromBody = (body, field) => {
|
|
7
|
-
if (!body) {
|
|
8
|
-
return null;
|
|
9
|
-
}
|
|
10
|
-
let value = null;
|
|
11
|
-
for (const key of Object.keys(body)) {
|
|
12
|
-
if (key.trim() === field.trim()) {
|
|
13
|
-
value = body[key];
|
|
14
|
-
break;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
return value;
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export const getFormData = (request, fillable) => {
|
|
21
|
-
let fields = fillable;
|
|
22
|
-
if (!Array.isArray(fillable)) {
|
|
23
|
-
fields = fillable[request.method] ? fillable[request.method] : [];
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const filtered = {};
|
|
27
|
-
for (const field of fields) {
|
|
28
|
-
filtered[field] = getInputFromBody(request.body, field);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return filtered;
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
export const getMergedFormData = (request, item, fillableFormData) => {
|
|
35
|
-
const formData = { ...item };
|
|
36
|
-
Object.keys(request.body).forEach((key) => {
|
|
37
|
-
formData[key] = fillableFormData[key];
|
|
38
|
-
});
|
|
39
|
-
return formData;
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
export const getFormValidation = (method, validations) => {
|
|
43
|
-
if (!validations) {
|
|
44
|
-
return undefined;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
if (validations[method]) {
|
|
48
|
-
return validations[method];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (validations.POST || validations.PUT) {
|
|
52
|
-
return undefined;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return validations;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export const callHooks = async (model, type, data) => {
|
|
59
|
-
if (model.hooks[type]) {
|
|
60
|
-
await model.hooks[type](data);
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
if (model.events[type]) {
|
|
64
|
-
const context = {
|
|
65
|
-
...data,
|
|
66
|
-
};
|
|
67
|
-
|
|
68
|
-
// Developers shouldn't be able to access transaction in events. Because
|
|
69
|
-
// we don't await for the events. If the developer uses the transaction and
|
|
70
|
-
// try to commit something, it would be lost cause the transaction could be
|
|
71
|
-
// already completed.
|
|
72
|
-
if (context.trx) {
|
|
73
|
-
delete context.trx;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
model.events[type](context);
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
export const getRelatedData = async (
|
|
81
|
-
data,
|
|
82
|
-
withArray,
|
|
83
|
-
model,
|
|
84
|
-
models,
|
|
85
|
-
database,
|
|
86
|
-
handler,
|
|
87
|
-
request
|
|
88
|
-
) => {
|
|
89
|
-
if (withArray.length === 0) {
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
for (const clientQuery of withArray) {
|
|
94
|
-
// Find the relation of the model. If the model doesn't have any relationship like the
|
|
95
|
-
// user wants, we can't show anything.
|
|
96
|
-
const definedRelation = model.instance.relations.find(
|
|
97
|
-
(relation) => relation.name === clientQuery.relationship
|
|
98
|
-
);
|
|
99
|
-
if (!definedRelation) {
|
|
100
|
-
throw new HttpResponse(400, {
|
|
101
|
-
message: `Undefined relation: ${clientQuery.relationship}`,
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Find the foreign model by the relationship
|
|
106
|
-
const foreignModel = models.find(
|
|
107
|
-
(model) => model.name === definedRelation.model
|
|
108
|
-
);
|
|
109
|
-
if (!foreignModel) {
|
|
110
|
-
continue;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
let dataField = "primaryKey";
|
|
114
|
-
let searchField = "foreignKey";
|
|
115
|
-
if (definedRelation.type !== RELATIONSHIPS.HAS_MANY) {
|
|
116
|
-
dataField = "foreignKey";
|
|
117
|
-
searchField = "primaryKey";
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// We should find the parent Primary Key values.
|
|
121
|
-
const parentPrimaryKeyValues = data.map(
|
|
122
|
-
(item) => item[definedRelation[dataField]]
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
// Selecting the special field for the relations
|
|
126
|
-
let selectColumns = "*";
|
|
127
|
-
if (clientQuery.fields.length > 0) {
|
|
128
|
-
selectColumns = [...clientQuery.fields, definedRelation[searchField]];
|
|
129
|
-
|
|
130
|
-
if (definedRelation.type === RELATIONSHIPS.HAS_MANY) {
|
|
131
|
-
selectColumns.push(definedRelation[dataField]);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// We should check if any select column is a relationship name. If so,
|
|
135
|
-
// we should remove that column name from the select columns
|
|
136
|
-
const possibleThirthLevelRelations = foreignModel.instance.relations.map(
|
|
137
|
-
(item) => item.name
|
|
138
|
-
);
|
|
139
|
-
|
|
140
|
-
// Deteching the other relations
|
|
141
|
-
const workList = selectColumns.filter((column) =>
|
|
142
|
-
possibleThirthLevelRelations.includes(column)
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
// Removing relationship values from the select column list
|
|
146
|
-
selectColumns = selectColumns.filter(
|
|
147
|
-
(column) => !possibleThirthLevelRelations.includes(column)
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
// Adding relationship request as the child objects
|
|
151
|
-
clientQuery.children = [
|
|
152
|
-
...clientQuery.children,
|
|
153
|
-
...workList.map((relationship) => {
|
|
154
|
-
return {
|
|
155
|
-
relationship,
|
|
156
|
-
fields: [],
|
|
157
|
-
children: [],
|
|
158
|
-
};
|
|
159
|
-
}),
|
|
160
|
-
];
|
|
161
|
-
|
|
162
|
-
// We should check if the column is defined on the table.
|
|
163
|
-
const undefinedColumns = selectColumns.filter(
|
|
164
|
-
(column) => !foreignModel.instance.columnNames.includes(column)
|
|
165
|
-
);
|
|
166
|
-
if (undefinedColumns.length > 0) {
|
|
167
|
-
throw new HttpResponse(400, {
|
|
168
|
-
message: `Undefined columns: ${undefinedColumns.join(", ")}`,
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// We should add the HAS_ONE relation's foreignKeys incase the developer
|
|
174
|
-
// wants the related data but didn't set the foreignKey column
|
|
175
|
-
if (Array.isArray(selectColumns)) {
|
|
176
|
-
const requiredForeignKeys = foreignModel.instance.relations
|
|
177
|
-
.filter((item) => item.type === RELATIONSHIPS.HAS_ONE)
|
|
178
|
-
.map((item) => item.foreignKey);
|
|
179
|
-
selectColumns.push(...requiredForeignKeys);
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Fetching related records by foreignKey and primary key values.
|
|
183
|
-
let relatedRecords = await database(foreignModel.instance.table)
|
|
184
|
-
.select(selectColumns)
|
|
185
|
-
.whereIn(definedRelation[searchField], parentPrimaryKeyValues);
|
|
186
|
-
|
|
187
|
-
// We should serialize related data if there is any serialization function
|
|
188
|
-
relatedRecords = await serializeData(
|
|
189
|
-
relatedRecords,
|
|
190
|
-
foreignModel.instance.serialize,
|
|
191
|
-
handler,
|
|
192
|
-
request
|
|
193
|
-
);
|
|
194
|
-
|
|
195
|
-
// We should hide hidden fields if there is any
|
|
196
|
-
filterHiddenFields(relatedRecords, foreignModel.instance.hiddens);
|
|
197
|
-
|
|
198
|
-
// We should try to get child data if there is any on the query
|
|
199
|
-
if (clientQuery.children.length > 0) {
|
|
200
|
-
await getRelatedData(
|
|
201
|
-
relatedRecords,
|
|
202
|
-
clientQuery.children,
|
|
203
|
-
foreignModel,
|
|
204
|
-
models,
|
|
205
|
-
database,
|
|
206
|
-
handler,
|
|
207
|
-
request
|
|
208
|
-
);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
// Binding relation data to the parent rows.
|
|
212
|
-
data.forEach((row) => {
|
|
213
|
-
let values = relatedRecords.filter(
|
|
214
|
-
(item) =>
|
|
215
|
-
item[definedRelation[searchField]] === row[definedRelation[dataField]]
|
|
216
|
-
);
|
|
217
|
-
if (definedRelation.type === RELATIONSHIPS.HAS_ONE) {
|
|
218
|
-
values = values.length > 0 ? values[0] : null;
|
|
219
|
-
}
|
|
220
|
-
row[definedRelation.name] = values;
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
};
|
|
224
|
-
|
|
225
|
-
export const filterHiddenFields = (itemArray, hiddens) => {
|
|
226
|
-
if (hiddens.length === 0 || itemArray.length === 0) {
|
|
227
|
-
return;
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
itemArray.forEach((item) => {
|
|
231
|
-
hiddens.forEach((hidden) => {
|
|
232
|
-
if (item[hidden] !== undefined) {
|
|
233
|
-
delete item[hidden];
|
|
234
|
-
}
|
|
235
|
-
});
|
|
236
|
-
});
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
export const bindTimestampValues = (formData, columnTypes = [], model) => {
|
|
240
|
-
for (const columnType of columnTypes) {
|
|
241
|
-
if (model.instance[columnType]) {
|
|
242
|
-
formData[model.instance[columnType]] = new Date();
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
const serialize = async (data, callback, request) => {
|
|
248
|
-
if (!callback) {
|
|
249
|
-
return data;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
if (Array.isArray(data)) {
|
|
253
|
-
return data.map((item) => callback(item, request));
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
return callback(data, request);
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
const globalSerializer = async (itemArray, handler, request) => {
|
|
260
|
-
const { Application } = await IoC.use("Config");
|
|
261
|
-
|
|
262
|
-
if (!Application.serializers) {
|
|
263
|
-
return itemArray;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
let callbacks = [];
|
|
267
|
-
// Push all runable serializer into callbacks.
|
|
268
|
-
Application.serializers.map((configSerializer) => {
|
|
269
|
-
// Serialize data for all requests types.
|
|
270
|
-
if (typeof configSerializer === "function") {
|
|
271
|
-
callbacks.push(configSerializer);
|
|
272
|
-
return;
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
// Serialize data with specific handler like "PAGINATE" or "SHOW".
|
|
276
|
-
if (
|
|
277
|
-
typeof configSerializer === "object" &&
|
|
278
|
-
configSerializer.handler.includes(handler)
|
|
279
|
-
) {
|
|
280
|
-
// Handle multiple serializer.
|
|
281
|
-
if (Array.isArray(configSerializer.serializer)) {
|
|
282
|
-
configSerializer.serializer.forEach((fn) => callbacks.push(fn));
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
callbacks.push(configSerializer.serializer);
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
});
|
|
289
|
-
|
|
290
|
-
while (callbacks.length !== 0) {
|
|
291
|
-
itemArray = serialize(itemArray, callbacks.shift(), request);
|
|
292
|
-
}
|
|
293
|
-
return itemArray;
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
export const serializeData = async (
|
|
297
|
-
itemArray,
|
|
298
|
-
modelSerializer,
|
|
299
|
-
handler,
|
|
300
|
-
request
|
|
301
|
-
) => {
|
|
302
|
-
itemArray = serialize(itemArray, modelSerializer, request);
|
|
303
|
-
itemArray = await globalSerializer(itemArray, handler, request);
|
|
304
|
-
return itemArray;
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
export const getParentColumn = (relation) => {
|
|
308
|
-
if (!relation) {
|
|
309
|
-
return null;
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
return camelCase(relation.foreignKey);
|
|
313
|
-
};
|
|
314
|
-
|
|
315
|
-
export const addForeignKeyQuery = (request, query, relation, parentModel) => {
|
|
316
|
-
if (relation && parentModel) {
|
|
317
|
-
const parentColumn = getParentColumn(relation);
|
|
318
|
-
query.where(relation.foreignKey, request.params[parentColumn]);
|
|
319
|
-
}
|
|
320
|
-
};
|
package/src/handlers/index.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import all from "./all.js";
|
|
2
|
-
import patch from "./patch.js";
|
|
3
|
-
import store from "./store.js";
|
|
4
|
-
import show from "./show.js";
|
|
5
|
-
import paginate from "./paginate.js";
|
|
6
|
-
import update from "./update.js";
|
|
7
|
-
import destroy from "./destroy.js";
|
|
8
|
-
|
|
9
|
-
export default { all, patch, store, show, paginate, update, destroy };
|
package/src/handlers/paginate.js
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
callHooks,
|
|
3
|
-
getRelatedData,
|
|
4
|
-
filterHiddenFields,
|
|
5
|
-
serializeData,
|
|
6
|
-
addForeignKeyQuery,
|
|
7
|
-
} from "./helpers.js";
|
|
8
|
-
import { HOOK_FUNCTIONS, HANDLERS } from "./../constants.js";
|
|
9
|
-
import QueryParser from "./../core/QueryParser.js";
|
|
10
|
-
|
|
11
|
-
export default async (context) => {
|
|
12
|
-
const { request, response, model, models, trx, relation, parentModel } =
|
|
13
|
-
context;
|
|
14
|
-
|
|
15
|
-
const queryParser = new QueryParser({ model, models });
|
|
16
|
-
|
|
17
|
-
// We should parse URL query string to use as condition in Lucid query
|
|
18
|
-
const conditions = queryParser.get(request.query);
|
|
19
|
-
|
|
20
|
-
// Creating a new database query
|
|
21
|
-
const query = trx.from(model.instance.table);
|
|
22
|
-
|
|
23
|
-
// Users should be able to select some fields to show.
|
|
24
|
-
queryParser.applyFields(query, conditions.fields);
|
|
25
|
-
|
|
26
|
-
// Binding parent id if there is.
|
|
27
|
-
addForeignKeyQuery(request, query, relation, parentModel);
|
|
28
|
-
|
|
29
|
-
// Users should be able to filter records
|
|
30
|
-
queryParser.applyWheres(query, conditions.q);
|
|
31
|
-
|
|
32
|
-
await callHooks(model, HOOK_FUNCTIONS.onBeforePaginate, {
|
|
33
|
-
...context,
|
|
34
|
-
conditions,
|
|
35
|
-
query,
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
// User should be able to select sorting fields and types
|
|
39
|
-
queryParser.applySorting(query, conditions.sort);
|
|
40
|
-
|
|
41
|
-
const result = await query.paginate({
|
|
42
|
-
perPage: conditions.per_page,
|
|
43
|
-
currentPage: conditions.page,
|
|
44
|
-
isLengthAware: true,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// We should try to get related data if there is any
|
|
48
|
-
await getRelatedData(
|
|
49
|
-
result.data,
|
|
50
|
-
conditions.with,
|
|
51
|
-
model,
|
|
52
|
-
models,
|
|
53
|
-
trx,
|
|
54
|
-
HANDLERS.PAGINATE,
|
|
55
|
-
request
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
await callHooks(model, HOOK_FUNCTIONS.onAfterPaginate, {
|
|
59
|
-
...context,
|
|
60
|
-
result,
|
|
61
|
-
conditions,
|
|
62
|
-
query,
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
// Serializing the data by the model's serialize method
|
|
66
|
-
result.data = await serializeData(
|
|
67
|
-
result.data,
|
|
68
|
-
model.instance.serialize,
|
|
69
|
-
HANDLERS.PAGINATE,
|
|
70
|
-
request
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
// Filtering hidden fields from the response data.
|
|
74
|
-
filterHiddenFields(result.data, model.instance.hiddens);
|
|
75
|
-
|
|
76
|
-
return response.json(result);
|
|
77
|
-
};
|
package/src/handlers/patch.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getFormData,
|
|
3
|
-
getMergedFormData,
|
|
4
|
-
getFormValidation,
|
|
5
|
-
callHooks,
|
|
6
|
-
filterHiddenFields,
|
|
7
|
-
bindTimestampValues,
|
|
8
|
-
serializeData,
|
|
9
|
-
addForeignKeyQuery,
|
|
10
|
-
} from "./helpers.js";
|
|
11
|
-
import Validator from "validatorjs";
|
|
12
|
-
import { HOOK_FUNCTIONS, TIMESTAMP_COLUMNS } from "./../constants.js";
|
|
13
|
-
import HttpResponse from "./../core/HttpResponse.js";
|
|
14
|
-
import { HANDLERS } from "./../constants.js";
|
|
15
|
-
|
|
16
|
-
export default async (context) => {
|
|
17
|
-
const { request, response, model, trx, relation, parentModel } = context;
|
|
18
|
-
|
|
19
|
-
const query = trx.from(model.instance.table);
|
|
20
|
-
|
|
21
|
-
// If there is a relation, we should bind it
|
|
22
|
-
addForeignKeyQuery(request, query, relation, parentModel);
|
|
23
|
-
|
|
24
|
-
await callHooks(model, HOOK_FUNCTIONS.onBeforeUpdateQuery, {
|
|
25
|
-
...context,
|
|
26
|
-
query,
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
let item = await query
|
|
30
|
-
.where(model.instance.primaryKey, request.params[model.instance.primaryKey])
|
|
31
|
-
.first();
|
|
32
|
-
if (!item) {
|
|
33
|
-
throw new HttpResponse(404, {
|
|
34
|
-
message: `The item is not found on ${model.name}.`,
|
|
35
|
-
});
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
await callHooks(model, HOOK_FUNCTIONS.onAfterUpdateQuery, {
|
|
39
|
-
...context,
|
|
40
|
-
item,
|
|
41
|
-
query,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
const fillableFormData = getFormData(request, model.instance.fillable);
|
|
45
|
-
const formData = getMergedFormData(request, item, fillableFormData);
|
|
46
|
-
|
|
47
|
-
const formValidationRules = getFormValidation(
|
|
48
|
-
request.method,
|
|
49
|
-
model.instance.validations
|
|
50
|
-
);
|
|
51
|
-
|
|
52
|
-
if (formValidationRules) {
|
|
53
|
-
const validation = new Validator(formData, formValidationRules);
|
|
54
|
-
if (validation.fails()) {
|
|
55
|
-
return response.status(400).json(validation.errors);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// We should bind the timestamp values
|
|
60
|
-
bindTimestampValues(formData, [TIMESTAMP_COLUMNS.UPDATED_AT], model);
|
|
61
|
-
|
|
62
|
-
await callHooks(model, HOOK_FUNCTIONS.onBeforeUpdate, {
|
|
63
|
-
...context,
|
|
64
|
-
item,
|
|
65
|
-
formData,
|
|
66
|
-
query,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
await query
|
|
70
|
-
.where(model.instance.primaryKey, item[model.instance.primaryKey])
|
|
71
|
-
.update(formData);
|
|
72
|
-
item = await trx(model.instance.table)
|
|
73
|
-
.where(model.instance.primaryKey, item[model.instance.primaryKey])
|
|
74
|
-
.first();
|
|
75
|
-
|
|
76
|
-
await callHooks(model, HOOK_FUNCTIONS.onAfterUpdate, {
|
|
77
|
-
...context,
|
|
78
|
-
item,
|
|
79
|
-
formData,
|
|
80
|
-
query,
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
// Serializing the data by the model's serialize method
|
|
84
|
-
item = await serializeData(
|
|
85
|
-
item,
|
|
86
|
-
model.instance.serialize,
|
|
87
|
-
HANDLERS.PATCH,
|
|
88
|
-
request
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
// Filtering hidden fields from the response data.
|
|
92
|
-
filterHiddenFields([item], model.instance.hiddens);
|
|
93
|
-
|
|
94
|
-
return response.json(item);
|
|
95
|
-
};
|
package/src/handlers/show.js
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
callHooks,
|
|
3
|
-
getRelatedData,
|
|
4
|
-
filterHiddenFields,
|
|
5
|
-
serializeData,
|
|
6
|
-
addForeignKeyQuery,
|
|
7
|
-
} from "./helpers.js";
|
|
8
|
-
import { HOOK_FUNCTIONS, HANDLERS } from "./../constants.js";
|
|
9
|
-
import HttpResponse from "./../core/HttpResponse.js";
|
|
10
|
-
import QueryParser from "./../core/QueryParser.js";
|
|
11
|
-
|
|
12
|
-
export default async (context) => {
|
|
13
|
-
const { request, response, model, models, trx, relation, parentModel } =
|
|
14
|
-
context;
|
|
15
|
-
const queryParser = new QueryParser({ model, models });
|
|
16
|
-
|
|
17
|
-
// We should parse URL query string to use as condition in Lucid query
|
|
18
|
-
const conditions = queryParser.get(request.query);
|
|
19
|
-
|
|
20
|
-
// Fetching item
|
|
21
|
-
const query = trx.from(model.instance.table);
|
|
22
|
-
|
|
23
|
-
// Users should be able to select some fields to show.
|
|
24
|
-
queryParser.applyFields(query, conditions.fields);
|
|
25
|
-
|
|
26
|
-
// If there is a relation, we should bind it
|
|
27
|
-
addForeignKeyQuery(request, query, relation, parentModel);
|
|
28
|
-
|
|
29
|
-
// Users should be able to filter records
|
|
30
|
-
queryParser.applyWheres(query, conditions.q);
|
|
31
|
-
|
|
32
|
-
// We should add this condition in here because of performance.
|
|
33
|
-
query.where(
|
|
34
|
-
model.instance.primaryKey,
|
|
35
|
-
request.params[model.instance.primaryKey]
|
|
36
|
-
);
|
|
37
|
-
|
|
38
|
-
await callHooks(model, HOOK_FUNCTIONS.onBeforeShow, {
|
|
39
|
-
...context,
|
|
40
|
-
query,
|
|
41
|
-
conditions,
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
let item = await query.first();
|
|
45
|
-
if (!item) {
|
|
46
|
-
throw new HttpResponse(404, {
|
|
47
|
-
message: `The item is not found on ${model.name}.`,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// We should try to get related data if there is any
|
|
52
|
-
await getRelatedData(
|
|
53
|
-
[item],
|
|
54
|
-
conditions.with,
|
|
55
|
-
model,
|
|
56
|
-
models,
|
|
57
|
-
trx,
|
|
58
|
-
HANDLERS.SHOW,
|
|
59
|
-
request
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
await callHooks(model, HOOK_FUNCTIONS.onAfterShow, {
|
|
63
|
-
...context,
|
|
64
|
-
query,
|
|
65
|
-
conditions,
|
|
66
|
-
item,
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
// Serializing the data by the model's serialize method
|
|
70
|
-
item = await serializeData(
|
|
71
|
-
item,
|
|
72
|
-
model.instance.serialize,
|
|
73
|
-
HANDLERS.SHOW,
|
|
74
|
-
request
|
|
75
|
-
);
|
|
76
|
-
|
|
77
|
-
// Filtering hidden fields from the response data.
|
|
78
|
-
filterHiddenFields([item], model.instance.hiddens);
|
|
79
|
-
|
|
80
|
-
return response.json(item);
|
|
81
|
-
};
|
package/src/handlers/store.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getFormData,
|
|
3
|
-
getFormValidation,
|
|
4
|
-
callHooks,
|
|
5
|
-
filterHiddenFields,
|
|
6
|
-
bindTimestampValues,
|
|
7
|
-
serializeData,
|
|
8
|
-
getParentColumn,
|
|
9
|
-
} from "./helpers.js";
|
|
10
|
-
import Validator from "validatorjs";
|
|
11
|
-
import { HOOK_FUNCTIONS, TIMESTAMP_COLUMNS, HANDLERS } from "./../constants.js";
|
|
12
|
-
|
|
13
|
-
export default async (context) => {
|
|
14
|
-
const { request, response, model, trx, relation, parentModel } = context;
|
|
15
|
-
|
|
16
|
-
const formData = getFormData(request, model.instance.fillable);
|
|
17
|
-
const formValidationRules = getFormValidation(
|
|
18
|
-
request.method,
|
|
19
|
-
model.instance.validations
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
if (formValidationRules) {
|
|
23
|
-
const validation = new Validator(formData, formValidationRules);
|
|
24
|
-
if (validation.fails()) {
|
|
25
|
-
return response.status(400).json(validation.errors);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
if (relation && parentModel) {
|
|
30
|
-
const parentColumn = getParentColumn(relation);
|
|
31
|
-
formData[relation.foreignKey] = request.params[parentColumn];
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// We should bind the timestamp values
|
|
35
|
-
bindTimestampValues(
|
|
36
|
-
formData,
|
|
37
|
-
[TIMESTAMP_COLUMNS.CREATED_AT, TIMESTAMP_COLUMNS.UPDATED_AT],
|
|
38
|
-
model
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
await callHooks(model, HOOK_FUNCTIONS.onBeforeInsert, {
|
|
42
|
-
...context,
|
|
43
|
-
formData,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
const [returningResult] = await trx(model.instance.table)
|
|
47
|
-
.insert(formData)
|
|
48
|
-
.returning(model.instance.primaryKey);
|
|
49
|
-
|
|
50
|
-
let insertedPrimaryKeyValue =
|
|
51
|
-
typeof returningResult === "number"
|
|
52
|
-
? returningResult
|
|
53
|
-
: returningResult[model.instance.primaryKey];
|
|
54
|
-
|
|
55
|
-
// If the user use a special primary key value, we should use that value
|
|
56
|
-
if (insertedPrimaryKeyValue === 0) {
|
|
57
|
-
insertedPrimaryKeyValue = formData[model.instance.primaryKey];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
let item = await trx(model.instance.table)
|
|
61
|
-
.where(model.instance.primaryKey, insertedPrimaryKeyValue)
|
|
62
|
-
.first();
|
|
63
|
-
|
|
64
|
-
await callHooks(model, HOOK_FUNCTIONS.onAfterInsert, {
|
|
65
|
-
...context,
|
|
66
|
-
formData,
|
|
67
|
-
item,
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// Serializing the data by the model's serialize method
|
|
71
|
-
item = await serializeData(
|
|
72
|
-
item,
|
|
73
|
-
model.instance.serialize,
|
|
74
|
-
HANDLERS.INSERT,
|
|
75
|
-
request
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
// Filtering hidden fields from the response data.
|
|
79
|
-
filterHiddenFields([item], model.instance.hiddens);
|
|
80
|
-
|
|
81
|
-
return response.json(item);
|
|
82
|
-
};
|