@webtypen/webframez-core 0.2.14 → 0.2.16

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 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
- - `next`: Function that signals when called that the request may be continued
47
- - `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.
48
- - `req`: The Request-Object
49
- - `res`: The Response-Object
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
- - `prefix`: A route path prefix used for all routes in this group:
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
- - `middleware`: An array of middleware-keys used for all routes in this group:
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
- Route.get("/", "TestController@test"); // Path: /test/
104
- Route.get("/test2", "TestController@test"); // Path: /test2/
101
+ Route.get("/", "TestController@test"); // Path: /test/
102
+ Route.get("/test2", "TestController@test"); // Path: /test2/
105
103
 
106
- Route.group({ middleware: ["auth"], prefix: "/auth" }, () => {
107
- Route.get("/data", "AuthController@data"); // Path: /test/auth/data; Middleware: auth
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
- - MongoDB Driver
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
- defaultConnection: "default",
129
- connections: {
130
- ["default"]: {
131
- driver: "mongodb",
132
- url: "mongodb://...",
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
- export class Test extends Model {
146
- __table = "test_table";
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
+ ```
@@ -1,4 +1,5 @@
1
1
  import { Request } from "../Router/Request";
2
+ type DatatableAutoApplyMatchModeType = "begin" | "end" | null;
2
3
  export declare class Datatable {
3
4
  collection: string | Function;
4
5
  aggregation: {
@@ -18,6 +19,8 @@ export declare class Datatable {
18
19
  perPage: number;
19
20
  onRow?: Function;
20
21
  onAttributes?: Function;
22
+ autoApplyFilter: DatatableAutoApplyMatchModeType;
23
+ autoApplySearch: DatatableAutoApplyMatchModeType;
21
24
  getInit(req: Request): Promise<any>;
22
25
  getAggregation(req: Request): Promise<any>;
23
26
  getSubAggregation(req: Request): Promise<any>;
@@ -36,3 +39,4 @@ export declare class Datatable {
36
39
  private formatFilterEntryVal;
37
40
  getFilterMatch(req: Request, searchOrFilter: any): Promise<any>;
38
41
  }
42
+ export {};
@@ -22,6 +22,8 @@ class Datatable {
22
22
  this.onPressLink = null;
23
23
  this.exports = null;
24
24
  this.perPage = 25;
25
+ this.autoApplyFilter = "begin";
26
+ this.autoApplySearch = null;
25
27
  }
26
28
  getInit(req) {
27
29
  return __awaiter(this, void 0, void 0, function* () {
@@ -62,7 +64,24 @@ class Datatable {
62
64
  }
63
65
  getAggregation(req) {
64
66
  return __awaiter(this, void 0, void 0, function* () {
65
- return typeof this.aggregation === "function" ? yield this.aggregation(req) : this.aggregation;
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
+ if (this.autoApplyFilter === "begin") {
70
+ return [{ $match: Object.assign({}, this.getFilterMatch(req, req.body.filter)) }, ...aggr];
71
+ }
72
+ else if (this.autoApplyFilter === "end") {
73
+ return [...aggr, { $match: Object.assign({}, this.getFilterMatch(req, req.body.filter)) }];
74
+ }
75
+ }
76
+ else if (this.autoApplySearch && req.body.search && typeof req.body.search === "object") {
77
+ if (this.autoApplySearch === "begin") {
78
+ return [{ $match: Object.assign({}, this.getFilterMatch(req, req.body.search)) }, ...aggr];
79
+ }
80
+ else if (this.autoApplySearch === "end") {
81
+ return [...aggr, { $match: Object.assign({}, this.getFilterMatch(req, req.body.search)) }];
82
+ }
83
+ }
84
+ return aggr;
66
85
  });
67
86
  }
68
87
  getSubAggregation(req) {
@@ -317,6 +336,28 @@ class Datatable {
317
336
  }
318
337
  break;
319
338
  }
339
+ if (value !== undefined && filterEl && filterEl.cast) {
340
+ if (typeof filterEl.cast === "function") {
341
+ value = yield filterEl.cast(value, entry, req);
342
+ }
343
+ else if (filterEl.cast === "string") {
344
+ value = value.toString();
345
+ }
346
+ else if (filterEl.cast === "objectId") {
347
+ if (value.length === 12 || value.length === 24) {
348
+ value = yield DBConnection_1.DBConnection.objectId(value);
349
+ }
350
+ }
351
+ else if (filterEl.cast === "integer") {
352
+ value = parseInt(value);
353
+ }
354
+ else if (filterEl.cast === "float") {
355
+ value = parseFloat(value);
356
+ }
357
+ else if (filterEl.cast === "boolean") {
358
+ value = value === true || value === 1 || value.toString() === "1" || value.toString() === "true" ? true : false;
359
+ }
360
+ }
320
361
  if (value !== undefined) {
321
362
  out[filterEl && filterEl.mapping && filterEl.mapping.trim() !== "" ? filterEl.mapping : key] = value;
322
363
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@webtypen/webframez-core",
3
- "version": "0.2.14",
3
+ "version": "0.2.16",
4
4
  "description": "The core package of the typescript based webframez (web-framework) by webtypen.de",
5
5
  "homepage": "https://webtypen.de/",
6
6
  "license": "MIT",
@@ -2,6 +2,8 @@ import { DBConnection } from "../Database/DBConnection";
2
2
  import { NumericFunctions } from "../Functions/NumericFunctions";
3
3
  import { Request } from "../Router/Request";
4
4
 
5
+ type DatatableAutoApplyMatchModeType = "begin" | "end" | null;
6
+
5
7
  export class Datatable {
6
8
  collection: string | Function = "";
7
9
  aggregation: { [key: string]: any } | Function | null = null;
@@ -13,6 +15,8 @@ export class Datatable {
13
15
  perPage: number = 25;
14
16
  onRow?: Function;
15
17
  onAttributes?: Function;
18
+ autoApplyFilter: DatatableAutoApplyMatchModeType = "begin";
19
+ autoApplySearch: DatatableAutoApplyMatchModeType = null;
16
20
 
17
21
  async getInit(req: Request) {
18
22
  const out: any = { table: req.body._table };
@@ -60,7 +64,21 @@ export class Datatable {
60
64
  }
61
65
 
62
66
  async getAggregation(req: Request) {
63
- return typeof this.aggregation === "function" ? await this.aggregation(req) : this.aggregation;
67
+ const aggr = typeof this.aggregation === "function" ? await this.aggregation(req) : this.aggregation;
68
+ if (this.autoApplyFilter && req.body.filter && typeof req.body.filter === "object") {
69
+ if (this.autoApplyFilter === "begin") {
70
+ return [{ $match: { ...this.getFilterMatch(req, req.body.filter) } }, ...aggr];
71
+ } else if (this.autoApplyFilter === "end") {
72
+ return [...aggr, { $match: { ...this.getFilterMatch(req, req.body.filter) } }];
73
+ }
74
+ } else if (this.autoApplySearch && req.body.search && typeof req.body.search === "object") {
75
+ if (this.autoApplySearch === "begin") {
76
+ return [{ $match: { ...this.getFilterMatch(req, req.body.search) } }, ...aggr];
77
+ } else if (this.autoApplySearch === "end") {
78
+ return [...aggr, { $match: { ...this.getFilterMatch(req, req.body.search) } }];
79
+ }
80
+ }
81
+ return aggr;
64
82
  }
65
83
 
66
84
  async getSubAggregation(req: Request) {
@@ -331,6 +349,24 @@ export class Datatable {
331
349
  break;
332
350
  }
333
351
 
352
+ if (value !== undefined && filterEl && filterEl.cast) {
353
+ if (typeof filterEl.cast === "function") {
354
+ value = await filterEl.cast(value, entry, req);
355
+ } else if (filterEl.cast === "string") {
356
+ value = value.toString();
357
+ } else if (filterEl.cast === "objectId") {
358
+ if (value.length === 12 || value.length === 24) {
359
+ value = await DBConnection.objectId(value);
360
+ }
361
+ } else if (filterEl.cast === "integer") {
362
+ value = parseInt(value);
363
+ } else if (filterEl.cast === "float") {
364
+ value = parseFloat(value);
365
+ } else if (filterEl.cast === "boolean") {
366
+ value = value === true || value === 1 || value.toString() === "1" || value.toString() === "true" ? true : false;
367
+ }
368
+ }
369
+
334
370
  if (value !== undefined) {
335
371
  out[filterEl && filterEl.mapping && filterEl.mapping.trim() !== "" ? filterEl.mapping : key] = value;
336
372
  }