@webtypen/webframez-core 0.2.14 → 0.2.15
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/README.md +73 -25
- package/dist/Datatable/Datatable.d.ts +2 -0
- package/dist/Datatable/Datatable.js +32 -1
- package/package.json +1 -1
- package/src/Datatable/Datatable.ts +27 -1
package/README.md
CHANGED
|
@@ -28,9 +28,7 @@ Alternatively, a function can be specified directly or a previously imported one
|
|
|
28
28
|
|
|
29
29
|
```ts
|
|
30
30
|
// Directly
|
|
31
|
-
Route.get("/", (req: Request, res: Response) =>
|
|
32
|
-
res.send({ status: "success" })
|
|
33
|
-
);
|
|
31
|
+
Route.get("/", (req: Request, res: Response) => res.send({ status: "success" }));
|
|
34
32
|
|
|
35
33
|
// Imported
|
|
36
34
|
import { myFunction } from "./myfunction";
|
|
@@ -43,10 +41,10 @@ Middleware functions are also registered in `app/Kernel.ts.` A middleware functi
|
|
|
43
41
|
|
|
44
42
|
Middleware functions are usually created under `app/Middleware`. A middleware function is called with the parameters (next, abort, req and res):
|
|
45
43
|
|
|
46
|
-
-
|
|
47
|
-
-
|
|
48
|
-
-
|
|
49
|
-
-
|
|
44
|
+
- `next`: Function that signals when called that the request may be continued
|
|
45
|
+
- `abort`: Function that aborts the request when called. An HTTP status code can be specified in the first parameter and a request body (usually text or JSON) in the second.
|
|
46
|
+
- `req`: The Request-Object
|
|
47
|
+
- `res`: The Response-Object
|
|
50
48
|
|
|
51
49
|
Alternatively, middleware functions can also be defined directly in Kernel.ts:
|
|
52
50
|
|
|
@@ -73,7 +71,7 @@ Route.get("/auth-data", "AuthController@authData", { middleware: ["auth"] });
|
|
|
73
71
|
|
|
74
72
|
With the grouping of routes, the code of the application can be significantly reduced and kept clear. Here's how the following configurations can be used with a multiple route definition:
|
|
75
73
|
|
|
76
|
-
-
|
|
74
|
+
- `prefix`: A route path prefix used for all routes in this group:
|
|
77
75
|
|
|
78
76
|
```ts
|
|
79
77
|
Route.group({ prefix: "/admin", () => {
|
|
@@ -82,7 +80,7 @@ Route.group({ prefix: "/admin", () => {
|
|
|
82
80
|
}});
|
|
83
81
|
```
|
|
84
82
|
|
|
85
|
-
-
|
|
83
|
+
- `middleware`: An array of middleware-keys used for all routes in this group:
|
|
86
84
|
|
|
87
85
|
```ts
|
|
88
86
|
Route.group({ middleware: ["auth"], () => {
|
|
@@ -100,12 +98,12 @@ Nesting of the route groups is also possible:
|
|
|
100
98
|
|
|
101
99
|
```ts
|
|
102
100
|
Route.group({ prefix: "/test" }, () => {
|
|
103
|
-
|
|
104
|
-
|
|
101
|
+
Route.get("/", "TestController@test"); // Path: /test/
|
|
102
|
+
Route.get("/test2", "TestController@test"); // Path: /test2/
|
|
105
103
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
Route.group({ middleware: ["auth"], prefix: "/auth" }, () => {
|
|
105
|
+
Route.get("/data", "AuthController@data"); // Path: /test/auth/data; Middleware: auth
|
|
106
|
+
});
|
|
109
107
|
});
|
|
110
108
|
```
|
|
111
109
|
|
|
@@ -117,7 +115,7 @@ The application can handle multiple database connections, but one is defined as
|
|
|
117
115
|
|
|
118
116
|
The connections are configured in the `config/database.ts` file. Each connection is given a unique key in the `connections` object and uses a driver. The following drivers are currently available:
|
|
119
117
|
|
|
120
|
-
-
|
|
118
|
+
- MongoDB Driver
|
|
121
119
|
|
|
122
120
|
Depending on the driver, the database connection must be configured with different parameters.
|
|
123
121
|
|
|
@@ -125,13 +123,13 @@ Depending on the driver, the database connection must be configured with differe
|
|
|
125
123
|
|
|
126
124
|
```ts
|
|
127
125
|
export default {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
126
|
+
defaultConnection: "default",
|
|
127
|
+
connections: {
|
|
128
|
+
["default"]: {
|
|
129
|
+
driver: "mongodb",
|
|
130
|
+
url: "mongodb://...",
|
|
131
|
+
},
|
|
133
132
|
},
|
|
134
|
-
},
|
|
135
133
|
};
|
|
136
134
|
```
|
|
137
135
|
|
|
@@ -140,9 +138,59 @@ export default {
|
|
|
140
138
|
Models are usually placed under `app/Models`. Each model class inherits from `Model` and must store the table / collection name, in which the models data sets are stored, in the `__table` attribute.
|
|
141
139
|
|
|
142
140
|
```ts
|
|
143
|
-
import { Model } from "@webtypen/webframez-core";
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
import { Model, hasMany, QueryBuilder } from "@webtypen/webframez-core";
|
|
142
|
+
import { File } from "./File";
|
|
143
|
+
import { Session } from "./Session";
|
|
144
|
+
|
|
145
|
+
export class User extends Model {
|
|
146
|
+
__table = "users";
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* @param File Dependency Model
|
|
150
|
+
* @param foreignKey
|
|
151
|
+
* @param localKey (optional)
|
|
152
|
+
* @param queryBuilderFunction (optional) customize the query
|
|
153
|
+
**/
|
|
154
|
+
@hasOne(() => File, "_user_avatar", "_id", (query: QueryBuilder) => {
|
|
155
|
+
query.where("status", "=", "uploaded");
|
|
156
|
+
})
|
|
157
|
+
avatar!: () => File;
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* @param File Dependency Model
|
|
161
|
+
* @param foreignKey
|
|
162
|
+
* @param localKey (optional)
|
|
163
|
+
* @param queryBuilderFunction (optional) customize the query
|
|
164
|
+
**/
|
|
165
|
+
@hasMany(() => Session, "_user")
|
|
166
|
+
sessions!: () => Session[];
|
|
147
167
|
}
|
|
148
168
|
```
|
|
169
|
+
|
|
170
|
+
### Load a model
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { User } from "../Models/User";
|
|
174
|
+
|
|
175
|
+
const users = await User.where("is_active", "=", true).get();
|
|
176
|
+
const testUser = await User.where("email", "=", "test@test.de").where("is_active", "=", true).first();
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
#### Dependency Injection
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
const sessions = await testUser.session();
|
|
183
|
+
const avatarUrl = await testUser.avatar()?.url;
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
##### Disable cache / force dependency-reload:
|
|
187
|
+
|
|
188
|
+
```ts
|
|
189
|
+
const refreshedData = await testUser.session({ force: true });
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
##### Get dependency-query:
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
const oldSessions = await testUser.session({ query: true }).where("date", "<", moment().subtract(30, "days").format("YYYY-MM-DD")).get();
|
|
196
|
+
```
|
|
@@ -18,6 +18,8 @@ export declare class Datatable {
|
|
|
18
18
|
perPage: number;
|
|
19
19
|
onRow?: Function;
|
|
20
20
|
onAttributes?: Function;
|
|
21
|
+
autoApplyFilter: boolean;
|
|
22
|
+
autoApplySearch: boolean;
|
|
21
23
|
getInit(req: Request): Promise<any>;
|
|
22
24
|
getAggregation(req: Request): Promise<any>;
|
|
23
25
|
getSubAggregation(req: Request): Promise<any>;
|
|
@@ -22,6 +22,8 @@ class Datatable {
|
|
|
22
22
|
this.onPressLink = null;
|
|
23
23
|
this.exports = null;
|
|
24
24
|
this.perPage = 25;
|
|
25
|
+
this.autoApplyFilter = true;
|
|
26
|
+
this.autoApplySearch = false;
|
|
25
27
|
}
|
|
26
28
|
getInit(req) {
|
|
27
29
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -62,7 +64,14 @@ class Datatable {
|
|
|
62
64
|
}
|
|
63
65
|
getAggregation(req) {
|
|
64
66
|
return __awaiter(this, void 0, void 0, function* () {
|
|
65
|
-
|
|
67
|
+
const aggr = typeof this.aggregation === "function" ? yield this.aggregation(req) : this.aggregation;
|
|
68
|
+
if (this.autoApplyFilter && req.body.filter && typeof req.body.filter === "object") {
|
|
69
|
+
return [{ $match: Object.assign({}, this.getFilterMatch(req, req.body.filter)) }];
|
|
70
|
+
}
|
|
71
|
+
else if (this.autoApplySearch && req.body.search && typeof req.body.search === "object") {
|
|
72
|
+
return [{ $match: Object.assign({}, this.getFilterMatch(req, req.body.search)) }];
|
|
73
|
+
}
|
|
74
|
+
return aggr;
|
|
66
75
|
});
|
|
67
76
|
}
|
|
68
77
|
getSubAggregation(req) {
|
|
@@ -317,6 +326,28 @@ class Datatable {
|
|
|
317
326
|
}
|
|
318
327
|
break;
|
|
319
328
|
}
|
|
329
|
+
if (value !== undefined && filterEl && filterEl.cast) {
|
|
330
|
+
if (typeof filterEl.cast === "function") {
|
|
331
|
+
value = yield filterEl.cast(value, entry, req);
|
|
332
|
+
}
|
|
333
|
+
else if (filterEl.cast === "string") {
|
|
334
|
+
value = value.toString();
|
|
335
|
+
}
|
|
336
|
+
else if (filterEl.cast === "objectId") {
|
|
337
|
+
if (value.length === 12 || value.length === 24) {
|
|
338
|
+
value = yield DBConnection_1.DBConnection.objectId(value);
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
else if (filterEl.cast === "integer") {
|
|
342
|
+
value = parseInt(value);
|
|
343
|
+
}
|
|
344
|
+
else if (filterEl.cast === "float") {
|
|
345
|
+
value = parseFloat(value);
|
|
346
|
+
}
|
|
347
|
+
else if (filterEl.cast === "boolean") {
|
|
348
|
+
value = value === true || value === 1 || value.toString() === "1" || value.toString() === "true" ? true : false;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
320
351
|
if (value !== undefined) {
|
|
321
352
|
out[filterEl && filterEl.mapping && filterEl.mapping.trim() !== "" ? filterEl.mapping : key] = value;
|
|
322
353
|
}
|
package/package.json
CHANGED
|
@@ -13,6 +13,8 @@ export class Datatable {
|
|
|
13
13
|
perPage: number = 25;
|
|
14
14
|
onRow?: Function;
|
|
15
15
|
onAttributes?: Function;
|
|
16
|
+
autoApplyFilter = true;
|
|
17
|
+
autoApplySearch = false;
|
|
16
18
|
|
|
17
19
|
async getInit(req: Request) {
|
|
18
20
|
const out: any = { table: req.body._table };
|
|
@@ -60,7 +62,13 @@ export class Datatable {
|
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
async getAggregation(req: Request) {
|
|
63
|
-
|
|
65
|
+
const aggr = typeof this.aggregation === "function" ? await this.aggregation(req) : this.aggregation;
|
|
66
|
+
if (this.autoApplyFilter && req.body.filter && typeof req.body.filter === "object") {
|
|
67
|
+
return [{ $match: { ...this.getFilterMatch(req, req.body.filter) } }];
|
|
68
|
+
} else if (this.autoApplySearch && req.body.search && typeof req.body.search === "object") {
|
|
69
|
+
return [{ $match: { ...this.getFilterMatch(req, req.body.search) } }];
|
|
70
|
+
}
|
|
71
|
+
return aggr;
|
|
64
72
|
}
|
|
65
73
|
|
|
66
74
|
async getSubAggregation(req: Request) {
|
|
@@ -331,6 +339,24 @@ export class Datatable {
|
|
|
331
339
|
break;
|
|
332
340
|
}
|
|
333
341
|
|
|
342
|
+
if (value !== undefined && filterEl && filterEl.cast) {
|
|
343
|
+
if (typeof filterEl.cast === "function") {
|
|
344
|
+
value = await filterEl.cast(value, entry, req);
|
|
345
|
+
} else if (filterEl.cast === "string") {
|
|
346
|
+
value = value.toString();
|
|
347
|
+
} else if (filterEl.cast === "objectId") {
|
|
348
|
+
if (value.length === 12 || value.length === 24) {
|
|
349
|
+
value = await DBConnection.objectId(value);
|
|
350
|
+
}
|
|
351
|
+
} else if (filterEl.cast === "integer") {
|
|
352
|
+
value = parseInt(value);
|
|
353
|
+
} else if (filterEl.cast === "float") {
|
|
354
|
+
value = parseFloat(value);
|
|
355
|
+
} else if (filterEl.cast === "boolean") {
|
|
356
|
+
value = value === true || value === 1 || value.toString() === "1" || value.toString() === "true" ? true : false;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
|
|
334
360
|
if (value !== undefined) {
|
|
335
361
|
out[filterEl && filterEl.mapping && filterEl.mapping.trim() !== "" ? filterEl.mapping : key] = value;
|
|
336
362
|
}
|