@clairejs/server 3.17.0 → 3.17.1
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 +2 -1
- package/dist/common/ControllerMetadata.d.ts +2 -2
- package/dist/common/request/endpoint-metadata.d.ts +12 -0
- package/dist/http/auth/AbstractHttpAuthorizer.d.ts +2 -2
- package/dist/http/common/HttpRequest.d.ts +1 -1
- package/dist/http/common/HttpRequest.js +7 -8
- package/dist/http/controller/AbstractHttpController.d.ts +2 -2
- package/dist/http/controller/AbstractHttpController.js +2 -2
- package/dist/http/controller/AbstractHttpMiddleware.d.ts +1 -1
- package/dist/http/controller/AbstractHttpRequestHandler.d.ts +8 -8
- package/dist/http/controller/AbstractHttpRequestHandler.js +14 -22
- package/dist/http/controller/CrudHttpController.d.ts +6 -6
- package/dist/http/controller/CrudHttpController.js +42 -84
- package/dist/http/controller/DefaultHttpRequestHandler.d.ts +2 -2
- package/dist/http/controller/DefaultHttpRequestHandler.js +9 -11
- package/dist/http/decorators.d.ts +5 -9
- package/dist/http/decorators.js +10 -22
- package/dist/http/repository/ICrudRepository.d.ts +3 -3
- package/dist/http/utils.d.ts +1 -3
- package/dist/http/utils.js +3 -20
- package/dist/index.d.ts +1 -6
- package/dist/index.js +1 -6
- package/dist/socket/AbstractServerSocketManager.d.ts +2 -2
- package/dist/socket/AbstractServerSocketManager.js +20 -70
- package/dist/socket/AbstractSocketController.d.ts +0 -1
- package/dist/socket/AbstractSocketController.js +0 -1
- package/dist/system/ClaireServer.d.ts +2 -3
- package/dist/system/ClaireServer.js +2 -10
- package/dist/system/ServerGlobalStore.d.ts +2 -2
- package/package.json +5 -5
- package/dist/common/request/EndpointMetadata.d.ts +0 -40
- package/dist/common/request/HttpEndpoint.d.ts +0 -7
- package/dist/common/request/HttpEndpoint.js +0 -1
- package/dist/common/request/MountedEndpointInfo.d.ts +0 -6
- package/dist/common/request/MountedEndpointInfo.js +0 -1
- package/dist/http/security/AbstractAccessCondition.d.ts +0 -7
- package/dist/http/security/AbstractAccessCondition.js +0 -2
- package/dist/http/security/access-conditions/FilterModelFieldAccessCondition.d.ts +0 -4
- package/dist/http/security/access-conditions/FilterModelFieldAccessCondition.js +0 -30
- package/dist/http/security/access-conditions/MaximumQueryLimit.d.ts +0 -8
- package/dist/http/security/access-conditions/MaximumQueryLimit.js +0 -31
- /package/dist/common/request/{EndpointMetadata.js → endpoint-metadata.js} +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ObjectMetadata } from "@clairejs/core";
|
|
2
|
-
import { EndpointMetadata } from "./request/
|
|
1
|
+
import { type ObjectMetadata } from "@clairejs/core";
|
|
2
|
+
import { type EndpointMetadata } from "./request/endpoint-metadata";
|
|
3
3
|
export interface ControllerMetadata extends ObjectMetadata {
|
|
4
4
|
fields: EndpointMetadata[];
|
|
5
5
|
permissionGroup?: string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type ApiInfo, type Constructor, type ObjectFieldMetadata } from "@clairejs/core";
|
|
2
|
+
import { type RequestDataSource } from "./types";
|
|
3
|
+
export interface EndpointMetadata extends ApiInfo, ObjectFieldMetadata {
|
|
4
|
+
controller: any;
|
|
5
|
+
handlerFunctionName: string;
|
|
6
|
+
params?: {
|
|
7
|
+
[index: number]: {
|
|
8
|
+
source?: RequestDataSource;
|
|
9
|
+
diClass?: Constructor<any>;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
2
2
|
import { HttpRequest } from "../common/HttpRequest";
|
|
3
3
|
export declare abstract class AbstractRequestAuthorizer {
|
|
4
|
-
abstract authorize(req: HttpRequest, endpoint:
|
|
4
|
+
abstract authorize(req: HttpRequest, endpoint: EndpointMetadata): Promise<void>;
|
|
5
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { HttpMethod, SocketMethod } from "@clairejs/core";
|
|
2
|
-
import { EndpointMetadata } from "../../common/request/
|
|
2
|
+
import { EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
3
3
|
import { IPrincipal } from "../../common/auth/IPrincipal";
|
|
4
4
|
import { IServerSocket } from "../../socket/IServerSocket";
|
|
5
5
|
export declare class HttpRequest {
|
|
@@ -46,25 +46,24 @@ export class HttpRequest {
|
|
|
46
46
|
this.authInfo = authInfo;
|
|
47
47
|
}
|
|
48
48
|
getParams() {
|
|
49
|
-
if (this.endpointMetadata?.
|
|
50
|
-
this.params.data = validateData(this.params.data, this.endpointMetadata.
|
|
49
|
+
if (this.endpointMetadata?.paramDto && !this.params.validated) {
|
|
50
|
+
this.params.data = validateData(this.params.data, this.endpointMetadata.paramDto);
|
|
51
51
|
this.params.validated = true;
|
|
52
52
|
}
|
|
53
53
|
return this.params.data;
|
|
54
54
|
}
|
|
55
55
|
getQuery() {
|
|
56
|
-
if (this.endpointMetadata?.
|
|
57
|
-
this.query.data = validateData(this.jsonParsing(this.query.data, this.endpointMetadata.
|
|
56
|
+
if (this.endpointMetadata?.queryDto && !this.query.validated) {
|
|
57
|
+
this.query.data = validateData(this.jsonParsing(this.query.data, this.endpointMetadata.queryDto), this.endpointMetadata.queryDto);
|
|
58
58
|
this.query.validated = true;
|
|
59
59
|
}
|
|
60
60
|
return this.query.data;
|
|
61
61
|
}
|
|
62
62
|
getBody() {
|
|
63
63
|
if (this.endpointMetadata &&
|
|
64
|
-
(this.endpointMetadata.
|
|
65
|
-
|
|
66
|
-
this.endpointMetadata
|
|
67
|
-
this.body.data = validateData(this.body.data, this.endpointMetadata.bodyValidationDto, false);
|
|
64
|
+
(this.endpointMetadata.method === HttpMethod.POST || this.endpointMetadata.method === HttpMethod.PUT) &&
|
|
65
|
+
this.endpointMetadata?.bodyDto) {
|
|
66
|
+
this.body.data = validateData(this.body.data, this.endpointMetadata.bodyDto, false);
|
|
68
67
|
this.body.validated = true;
|
|
69
68
|
}
|
|
70
69
|
return this.body.data;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { ITransactionFactory } from "@clairejs/orm";
|
|
1
|
+
import { type ITransactionFactory } from "@clairejs/orm";
|
|
2
2
|
import { AbstractController } from "../../common/AbstractController";
|
|
3
|
-
import { EndpointMetadata } from "../../common/request/
|
|
3
|
+
import { type EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
4
4
|
export declare abstract class AbstractHttpController extends AbstractController {
|
|
5
5
|
protected readonly databaseAdapter: ITransactionFactory;
|
|
6
6
|
constructor(databaseAdapter: ITransactionFactory);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getObjectMetadata } from "@clairejs/core";
|
|
2
2
|
import { AbstractController } from "../../common/AbstractController";
|
|
3
3
|
const isEndpoint = (metadata) => {
|
|
4
|
-
return !!metadata.
|
|
4
|
+
return !!metadata.method || metadata.description !== undefined;
|
|
5
5
|
};
|
|
6
6
|
export class AbstractHttpController extends AbstractController {
|
|
7
7
|
databaseAdapter;
|
|
@@ -16,6 +16,6 @@ export class AbstractHttpController extends AbstractController {
|
|
|
16
16
|
}
|
|
17
17
|
return controllerMetadata.fields
|
|
18
18
|
.filter((f) => isEndpoint(f))
|
|
19
|
-
.map((f) => ({ ...f,
|
|
19
|
+
.map((f) => ({ ...f, apiGroup: controllerMetadata.permissionGroup }));
|
|
20
20
|
}
|
|
21
21
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { EndpointMetadata } from "../../common/request/
|
|
1
|
+
import { EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
2
2
|
import { HttpRequest } from "../common/HttpRequest";
|
|
3
3
|
import { HttpResponse } from "../common/HttpResponse";
|
|
4
4
|
export declare abstract class AbstractHttpMiddleware {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { AbstractLogger } from "@clairejs/core";
|
|
2
|
-
import { HttpData } from "../../common/request/HttpData";
|
|
3
|
-
import {
|
|
4
|
-
import { HttpResponse } from "../common/HttpResponse";
|
|
5
|
-
import { ControllerMetadata } from "../../common/ControllerMetadata";
|
|
6
|
-
import { CorsConfig } from "../security/cors";
|
|
7
|
-
import { AbstractHttpMiddleware } from "./AbstractHttpMiddleware";
|
|
2
|
+
import { type HttpData } from "../../common/request/HttpData";
|
|
3
|
+
import { type EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
4
|
+
import { type HttpResponse } from "../common/HttpResponse";
|
|
5
|
+
import { type ControllerMetadata } from "../../common/ControllerMetadata";
|
|
6
|
+
import { type CorsConfig } from "../security/cors";
|
|
7
|
+
import { type AbstractHttpMiddleware } from "./AbstractHttpMiddleware";
|
|
8
8
|
export declare abstract class AbstractHttpRequestHandler {
|
|
9
9
|
readonly mountPoint: string;
|
|
10
10
|
readonly logger: AbstractLogger;
|
|
11
11
|
private mountedEndpointInfo?;
|
|
12
12
|
corsConfig?: CorsConfig;
|
|
13
13
|
constructor(mountPoint: string, logger: AbstractLogger);
|
|
14
|
-
protected
|
|
15
|
-
getMountedEndpointInfo(): Promise<
|
|
14
|
+
protected resolveMountPoint(controllerMetadata: ControllerMetadata, mappingUrls: string[]): string;
|
|
15
|
+
getMountedEndpointInfo(): Promise<EndpointMetadata[]>;
|
|
16
16
|
abstract getMiddleware(): Promise<AbstractHttpMiddleware[]>;
|
|
17
17
|
abstract handle(httpData: HttpData): Promise<HttpResponse<any>>;
|
|
18
18
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { getObjectMetadata, getServiceProvider, SocketMethod } from "@clairejs/core";
|
|
2
|
-
import { getEndpointId } from "../utils";
|
|
1
|
+
import { getObjectMetadata, getServiceProvider, HttpMethod, SocketMethod } from "@clairejs/core";
|
|
3
2
|
import { AbstractHttpController } from "./AbstractHttpController";
|
|
4
3
|
export class AbstractHttpRequestHandler {
|
|
5
4
|
mountPoint;
|
|
@@ -10,7 +9,7 @@ export class AbstractHttpRequestHandler {
|
|
|
10
9
|
this.mountPoint = mountPoint;
|
|
11
10
|
this.logger = logger;
|
|
12
11
|
}
|
|
13
|
-
|
|
12
|
+
resolveMountPoint(controllerMetadata, mappingUrls) {
|
|
14
13
|
if (!controllerMetadata) {
|
|
15
14
|
return "";
|
|
16
15
|
}
|
|
@@ -30,33 +29,26 @@ export class AbstractHttpRequestHandler {
|
|
|
30
29
|
for (const controller of controllers) {
|
|
31
30
|
const controllerMetadata = getObjectMetadata(controller.constructor);
|
|
32
31
|
const allEndpointMetadata = controller.getEndpointMetadata();
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
controller: controller,
|
|
43
|
-
handlerFunctionName: endpointMetadata.name,
|
|
32
|
+
result.push(...allEndpointMetadata.map((endpoint) => {
|
|
33
|
+
const mount = endpoint.method === SocketMethod.MESSAGE
|
|
34
|
+
? endpoint.mount
|
|
35
|
+
: this.resolveMountPoint(controllerMetadata, [this.mountPoint || "/", endpoint.mount]);
|
|
36
|
+
return {
|
|
37
|
+
...endpoint,
|
|
38
|
+
readOnly: endpoint.method === HttpMethod.GET,
|
|
39
|
+
mount,
|
|
40
|
+
id: `${endpoint.method}:${mount}`,
|
|
44
41
|
};
|
|
45
|
-
|
|
46
|
-
endpointMetadata,
|
|
47
|
-
endpoint,
|
|
48
|
-
});
|
|
49
|
-
}
|
|
42
|
+
}));
|
|
50
43
|
}
|
|
51
44
|
//-- add to final to-be-mounted endpoints
|
|
52
45
|
const mountedEndpointInfo = [];
|
|
53
46
|
for (const endpointInfo of result) {
|
|
54
47
|
//-- check overriden endpoints
|
|
55
|
-
const overridingEndpoint = mountedEndpointInfo.find((info) => info.
|
|
56
|
-
info.endpoint.httpMethod === endpointInfo.endpoint.httpMethod);
|
|
48
|
+
const overridingEndpoint = mountedEndpointInfo.find((info) => info.mount === endpointInfo.mount && info.method === endpointInfo.method);
|
|
57
49
|
if (overridingEndpoint) {
|
|
58
50
|
//-- if this endpoint has an other overriden endpoints then do not mount
|
|
59
|
-
this.logger?.warn(`Implicit overriding endpoint: ${
|
|
51
|
+
this.logger?.warn(`Implicit overriding endpoint: ${overridingEndpoint.method}:${overridingEndpoint.mount} of ${overridingEndpoint.controller?.constructor.name}:${overridingEndpoint.handlerFunctionName}`, `Ignore ${endpointInfo.method}:${endpointInfo.mount} of ${endpointInfo.controller?.constructor.name}:${endpointInfo.handlerFunctionName}`);
|
|
60
52
|
}
|
|
61
53
|
else {
|
|
62
54
|
mountedEndpointInfo.push(endpointInfo);
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { CreateManyResponseBody, GetManyResponseBody,
|
|
2
|
-
import { IQueryProvider, ITransactionFactory } from "@clairejs/orm";
|
|
3
|
-
import { HttpRequest } from "../common/HttpRequest";
|
|
4
|
-
import { HttpResponse } from "../common/HttpResponse";
|
|
5
|
-
import { EndpointMetadata } from "../../common/request/
|
|
1
|
+
import { type Constructor, type CreateManyResponseBody, type GetManyResponseBody, type Identifiable, type ModelMetadata, type UpdateManyResponse } from "@clairejs/core";
|
|
2
|
+
import { type IQueryProvider, type ITransactionFactory } from "@clairejs/orm";
|
|
3
|
+
import { type HttpRequest } from "../common/HttpRequest";
|
|
4
|
+
import { type HttpResponse } from "../common/HttpResponse";
|
|
5
|
+
import { type EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
6
6
|
import { AbstractHttpController } from "./AbstractHttpController";
|
|
7
|
-
import { ICrudRepository } from "../repository/ICrudRepository";
|
|
7
|
+
import { type ICrudRepository } from "../repository/ICrudRepository";
|
|
8
8
|
export declare class CrudHttpController<T extends Identifiable> extends AbstractHttpController {
|
|
9
9
|
protected readonly model: Constructor<T>;
|
|
10
10
|
protected readonly crudRepository: ICrudRepository<T>;
|
|
@@ -10,15 +10,12 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
10
10
|
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
11
11
|
return function (target, key) { decorator(target, key, paramIndex); }
|
|
12
12
|
};
|
|
13
|
-
import {
|
|
13
|
+
import { deepMerge, getCreateManyBodyValidator, getCreateManyResponseValidator, getGetManyQueryValidator, getGetManyResponseValidator, getObjectMetadata, getServiceProvider, getUpdateManyBodyValidator, getUpdateManyQueryValidator, getUpdateManyResponseValidator, getUpdateRecordsBodyValidator, getUpdateRecordsQueryValidator, HttpMethod, omitData, } from "@clairejs/core";
|
|
14
14
|
import { Transactional, PropagationMode } from "@clairejs/orm";
|
|
15
|
-
import { HttpRequest } from "../common/HttpRequest";
|
|
16
15
|
import { ResponseBuilder } from "../common/HttpResponse";
|
|
17
16
|
import { AbstractPrincipalResolver } from "../../common/auth/AbstractPrincipalResolver";
|
|
18
|
-
import {
|
|
17
|
+
import { ApiDescription, Raw } from "../decorators";
|
|
19
18
|
import { AbstractHttpController } from "./AbstractHttpController";
|
|
20
|
-
import { MaximumQueryLimit } from "../security/access-conditions/MaximumQueryLimit";
|
|
21
|
-
import { FilterModelFieldAccessCondition } from "../security/access-conditions/FilterModelFieldAccessCondition";
|
|
22
19
|
export class CrudHttpController extends AbstractHttpController {
|
|
23
20
|
model;
|
|
24
21
|
crudRepository;
|
|
@@ -48,15 +45,14 @@ export class CrudHttpController extends AbstractHttpController {
|
|
|
48
45
|
*/
|
|
49
46
|
createManyEndpoinMetadata() {
|
|
50
47
|
const endpointMetadata = {};
|
|
51
|
-
endpointMetadata.
|
|
52
|
-
endpointMetadata.
|
|
53
|
-
endpointMetadata.name =
|
|
54
|
-
endpointMetadata.
|
|
48
|
+
endpointMetadata.method = HttpMethod.POST;
|
|
49
|
+
endpointMetadata.mount = this.getMountedUrl();
|
|
50
|
+
endpointMetadata.name = "createMany" + this.model.name;
|
|
51
|
+
endpointMetadata.handlerFunctionName = CrudHttpController.prototype.createMany.name;
|
|
55
52
|
//-- body dto ------------------------------------
|
|
56
|
-
endpointMetadata.
|
|
53
|
+
endpointMetadata.bodyDto = getCreateManyBodyValidator(this.modelMetadata);
|
|
57
54
|
//-- response dto ------------------------------------
|
|
58
|
-
endpointMetadata.
|
|
59
|
-
endpointMetadata.accessConditions = [];
|
|
55
|
+
endpointMetadata.responseDto = getCreateManyResponseValidator(this.modelMetadata);
|
|
60
56
|
endpointMetadata.params = { 0: { source: "raw" } };
|
|
61
57
|
return endpointMetadata;
|
|
62
58
|
}
|
|
@@ -66,19 +62,14 @@ export class CrudHttpController extends AbstractHttpController {
|
|
|
66
62
|
getManyEndpointMetadata() {
|
|
67
63
|
//-- get all
|
|
68
64
|
const endpointMetadata = {};
|
|
69
|
-
endpointMetadata.
|
|
70
|
-
endpointMetadata.
|
|
71
|
-
endpointMetadata.
|
|
72
|
-
endpointMetadata.
|
|
65
|
+
endpointMetadata.method = HttpMethod.GET;
|
|
66
|
+
endpointMetadata.mount = this.getMountedUrl();
|
|
67
|
+
endpointMetadata.handlerFunctionName = CrudHttpController.prototype.getMany.name;
|
|
68
|
+
endpointMetadata.name = "getAll" + this.model.name;
|
|
73
69
|
//-- query dto
|
|
74
|
-
endpointMetadata.
|
|
70
|
+
endpointMetadata.queryDto = getGetManyQueryValidator(this.modelMetadata);
|
|
75
71
|
//-- response dto ------------------------------------
|
|
76
|
-
endpointMetadata.
|
|
77
|
-
//-- access condition
|
|
78
|
-
endpointMetadata.accessConditions = [
|
|
79
|
-
FilterModelFieldAccessCondition(this.model, "model_projection", (request) => request.getQuery().projection),
|
|
80
|
-
MaximumQueryLimit,
|
|
81
|
-
];
|
|
72
|
+
endpointMetadata.responseDto = getGetManyResponseValidator(this.modelMetadata);
|
|
82
73
|
endpointMetadata.params = { 0: { source: "raw" } };
|
|
83
74
|
return endpointMetadata;
|
|
84
75
|
}
|
|
@@ -87,50 +78,31 @@ export class CrudHttpController extends AbstractHttpController {
|
|
|
87
78
|
*/
|
|
88
79
|
updateManyEndpointMetadata() {
|
|
89
80
|
const endpointMetadata = {};
|
|
90
|
-
endpointMetadata.
|
|
91
|
-
endpointMetadata.
|
|
92
|
-
endpointMetadata.
|
|
93
|
-
endpointMetadata.
|
|
81
|
+
endpointMetadata.method = HttpMethod.PUT;
|
|
82
|
+
endpointMetadata.mount = this.getMountedUrl();
|
|
83
|
+
endpointMetadata.handlerFunctionName = CrudHttpController.prototype.updateMany.name;
|
|
84
|
+
endpointMetadata.name = "update" + this.model.name;
|
|
94
85
|
//-- queries dto ---------------------------------
|
|
95
|
-
endpointMetadata.
|
|
86
|
+
endpointMetadata.queryDto = getUpdateManyQueryValidator(this.modelMetadata);
|
|
96
87
|
//-- body dto ------------------------------------
|
|
97
|
-
endpointMetadata.
|
|
88
|
+
endpointMetadata.bodyDto = getUpdateManyBodyValidator(this.modelMetadata);
|
|
98
89
|
//-- response dto ------------------------------------
|
|
99
|
-
endpointMetadata.
|
|
100
|
-
//-- access condition
|
|
101
|
-
endpointMetadata.accessConditions = [
|
|
102
|
-
FilterModelFieldAccessCondition(this.model, "restrict_update_fields", (request) => {
|
|
103
|
-
const updateBody = request.getBody().update;
|
|
104
|
-
if (!updateBody) {
|
|
105
|
-
return [];
|
|
106
|
-
}
|
|
107
|
-
return Object.keys(leanData(updateBody));
|
|
108
|
-
}),
|
|
109
|
-
];
|
|
90
|
+
endpointMetadata.responseDto = getUpdateManyResponseValidator(this.modelMetadata);
|
|
110
91
|
endpointMetadata.params = { 0: { source: "raw" } };
|
|
111
92
|
return endpointMetadata;
|
|
112
93
|
}
|
|
113
94
|
updateRecordsEndpointMetadata() {
|
|
114
95
|
const endpointMetadata = {};
|
|
115
|
-
endpointMetadata.
|
|
116
|
-
endpointMetadata.
|
|
117
|
-
endpointMetadata.
|
|
118
|
-
endpointMetadata.
|
|
96
|
+
endpointMetadata.method = HttpMethod.PUT;
|
|
97
|
+
endpointMetadata.mount = `${this.getMountedUrl()}/records`;
|
|
98
|
+
endpointMetadata.handlerFunctionName = CrudHttpController.prototype.updateRecords.name;
|
|
99
|
+
endpointMetadata.name = "updateRecords" + this.model.name;
|
|
119
100
|
//-- queries dto ---------------------------------
|
|
120
|
-
endpointMetadata.
|
|
101
|
+
endpointMetadata.queryDto = getUpdateRecordsQueryValidator();
|
|
121
102
|
//-- body dto ------------------------------------
|
|
122
|
-
endpointMetadata.
|
|
103
|
+
endpointMetadata.bodyDto = getUpdateRecordsBodyValidator(this.modelMetadata);
|
|
123
104
|
//-- response dto ------------------------------------
|
|
124
|
-
endpointMetadata.
|
|
125
|
-
//-- access condition
|
|
126
|
-
endpointMetadata.accessConditions = [
|
|
127
|
-
FilterModelFieldAccessCondition(this.model, "restrict_update_fields", (request) => {
|
|
128
|
-
const updates = request.getBody();
|
|
129
|
-
return updates.records
|
|
130
|
-
.flatMap(({ id, ...update }) => Object.keys(leanData(update) || {}))
|
|
131
|
-
.reduce(uniqueReducer, []);
|
|
132
|
-
}),
|
|
133
|
-
];
|
|
105
|
+
endpointMetadata.responseDto = getUpdateManyResponseValidator(this.modelMetadata);
|
|
134
106
|
return endpointMetadata;
|
|
135
107
|
}
|
|
136
108
|
/**
|
|
@@ -138,16 +110,14 @@ export class CrudHttpController extends AbstractHttpController {
|
|
|
138
110
|
*/
|
|
139
111
|
deleteManyEndpoinMetadata() {
|
|
140
112
|
const endpointMetadata = {};
|
|
141
|
-
endpointMetadata.
|
|
142
|
-
endpointMetadata.
|
|
143
|
-
endpointMetadata.
|
|
144
|
-
endpointMetadata.
|
|
113
|
+
endpointMetadata.method = HttpMethod.DEL;
|
|
114
|
+
endpointMetadata.mount = this.getMountedUrl();
|
|
115
|
+
endpointMetadata.handlerFunctionName = CrudHttpController.prototype.deleteMany.name;
|
|
116
|
+
endpointMetadata.name = "delete" + this.model.name;
|
|
145
117
|
//-- queries ---------------------------------
|
|
146
|
-
endpointMetadata.
|
|
147
|
-
endpointMetadata.
|
|
118
|
+
endpointMetadata.queryDto = getUpdateManyQueryValidator(this.modelMetadata);
|
|
119
|
+
endpointMetadata.responseDto = getUpdateManyResponseValidator(this.modelMetadata);
|
|
148
120
|
endpointMetadata.params = { 0: { source: "raw" } };
|
|
149
|
-
//-- access condition
|
|
150
|
-
endpointMetadata.accessConditions = [];
|
|
151
121
|
return endpointMetadata;
|
|
152
122
|
}
|
|
153
123
|
/**
|
|
@@ -184,17 +154,10 @@ export class CrudHttpController extends AbstractHttpController {
|
|
|
184
154
|
}
|
|
185
155
|
//-- merge with super
|
|
186
156
|
for (const endpoint of crudEnpointMetadata) {
|
|
187
|
-
const index = allEndpoints.findIndex((e) => (e.
|
|
188
|
-
(e.name === endpoint.name && (!e.
|
|
157
|
+
const index = allEndpoints.findIndex((e) => (e.method === endpoint.method && e.mount === endpoint.mount) ||
|
|
158
|
+
(e.name === endpoint.name && (!e.method || !e.mount)));
|
|
189
159
|
if (index >= 0) {
|
|
190
|
-
allEndpoints[index]
|
|
191
|
-
...endpoint,
|
|
192
|
-
...allEndpoints[index],
|
|
193
|
-
accessConditions: [
|
|
194
|
-
...(endpoint.accessConditions || []),
|
|
195
|
-
...(allEndpoints[index].accessConditions || []),
|
|
196
|
-
],
|
|
197
|
-
};
|
|
160
|
+
deepMerge(allEndpoints[index], endpoint, true);
|
|
198
161
|
}
|
|
199
162
|
else {
|
|
200
163
|
allEndpoints.push(endpoint);
|
|
@@ -260,44 +223,39 @@ export class CrudHttpController extends AbstractHttpController {
|
|
|
260
223
|
__decorate([
|
|
261
224
|
Transactional(PropagationMode.INHERIT_OR_CREATE),
|
|
262
225
|
ApiDescription("Update records of this table."),
|
|
263
|
-
AccessCondition([]),
|
|
264
226
|
__param(0, Raw()),
|
|
265
227
|
__metadata("design:type", Function),
|
|
266
|
-
__metadata("design:paramtypes", [
|
|
228
|
+
__metadata("design:paramtypes", [Function]),
|
|
267
229
|
__metadata("design:returntype", Promise)
|
|
268
230
|
], CrudHttpController.prototype, "updateRecords", null);
|
|
269
231
|
__decorate([
|
|
270
232
|
Transactional(PropagationMode.INHERIT_OR_CREATE),
|
|
271
233
|
ApiDescription("Create records of this table."),
|
|
272
|
-
AccessCondition([]),
|
|
273
234
|
__param(0, Raw()),
|
|
274
235
|
__metadata("design:type", Function),
|
|
275
|
-
__metadata("design:paramtypes", [
|
|
236
|
+
__metadata("design:paramtypes", [Function]),
|
|
276
237
|
__metadata("design:returntype", Promise)
|
|
277
238
|
], CrudHttpController.prototype, "createMany", null);
|
|
278
239
|
__decorate([
|
|
279
|
-
AccessCondition([]),
|
|
280
240
|
ApiDescription("Get records of this table."),
|
|
281
241
|
__param(0, Raw()),
|
|
282
242
|
__metadata("design:type", Function),
|
|
283
|
-
__metadata("design:paramtypes", [
|
|
243
|
+
__metadata("design:paramtypes", [Function]),
|
|
284
244
|
__metadata("design:returntype", Promise)
|
|
285
245
|
], CrudHttpController.prototype, "getMany", null);
|
|
286
246
|
__decorate([
|
|
287
247
|
Transactional(PropagationMode.INHERIT_OR_CREATE),
|
|
288
248
|
ApiDescription("Find and update records which match search condition."),
|
|
289
|
-
AccessCondition([]),
|
|
290
249
|
__param(0, Raw()),
|
|
291
250
|
__metadata("design:type", Function),
|
|
292
|
-
__metadata("design:paramtypes", [
|
|
251
|
+
__metadata("design:paramtypes", [Function]),
|
|
293
252
|
__metadata("design:returntype", Promise)
|
|
294
253
|
], CrudHttpController.prototype, "updateMany", null);
|
|
295
254
|
__decorate([
|
|
296
255
|
Transactional(PropagationMode.INHERIT_OR_CREATE),
|
|
297
256
|
ApiDescription("Find and remove records which match search condition."),
|
|
298
|
-
AccessCondition([]),
|
|
299
257
|
__param(0, Raw()),
|
|
300
258
|
__metadata("design:type", Function),
|
|
301
|
-
__metadata("design:paramtypes", [
|
|
259
|
+
__metadata("design:paramtypes", [Function]),
|
|
302
260
|
__metadata("design:returntype", Promise)
|
|
303
261
|
], CrudHttpController.prototype, "deleteMany", null);
|
|
@@ -3,8 +3,8 @@ import { HttpResponse } from "../common/HttpResponse";
|
|
|
3
3
|
import { AbstractPrincipalResolver } from "../../common/auth/AbstractPrincipalResolver";
|
|
4
4
|
import { HttpRequest } from "../common/HttpRequest";
|
|
5
5
|
import { AbstractRequestAuthorizer } from "../auth/AbstractHttpAuthorizer";
|
|
6
|
-
import { MountedEndpointInfo } from "../../common/request/MountedEndpointInfo";
|
|
7
6
|
import { HttpData } from "../../common/request/HttpData";
|
|
7
|
+
import { EndpointMetadata } from "../../common/request/endpoint-metadata";
|
|
8
8
|
import { AbstractHttpMiddleware } from "./AbstractHttpMiddleware";
|
|
9
9
|
import { AbstractHttpRequestHandler } from "./AbstractHttpRequestHandler";
|
|
10
10
|
export declare class DefaultHttpRequestHandler extends AbstractHttpRequestHandler {
|
|
@@ -13,7 +13,7 @@ export declare class DefaultHttpRequestHandler extends AbstractHttpRequestHandle
|
|
|
13
13
|
readonly principalResolver: AbstractPrincipalResolver;
|
|
14
14
|
private _middleware;
|
|
15
15
|
constructor(logger: AbstractLogger, authorizationProvider: AbstractRequestAuthorizer, principalResolver: AbstractPrincipalResolver);
|
|
16
|
-
protected handleRequest(endpoint:
|
|
16
|
+
protected handleRequest(endpoint: EndpointMetadata, req: HttpRequest): Promise<HttpResponse<any>>;
|
|
17
17
|
exit(): void;
|
|
18
18
|
private getResponse;
|
|
19
19
|
handle(httpData: HttpData): Promise<HttpResponse<any>>;
|
|
@@ -31,7 +31,7 @@ let DefaultHttpRequestHandler = class DefaultHttpRequestHandler extends Abstract
|
|
|
31
31
|
}
|
|
32
32
|
async handleRequest(endpoint, req) {
|
|
33
33
|
//-- supply correct order of params into handler
|
|
34
|
-
const params = Object.values(endpoint.
|
|
34
|
+
const params = Object.values(endpoint.params || {}).map((p) => {
|
|
35
35
|
switch (p.source) {
|
|
36
36
|
case "body":
|
|
37
37
|
return req.getBody();
|
|
@@ -45,10 +45,10 @@ let DefaultHttpRequestHandler = class DefaultHttpRequestHandler extends Abstract
|
|
|
45
45
|
return req;
|
|
46
46
|
}
|
|
47
47
|
});
|
|
48
|
-
const response = await endpoint.
|
|
48
|
+
const response = await endpoint.controller[endpoint.handlerFunctionName](...params);
|
|
49
49
|
//-- validate response value against response dto
|
|
50
|
-
if (endpoint.
|
|
51
|
-
response.value = stripData(response.value, endpoint.
|
|
50
|
+
if (endpoint.responseDto) {
|
|
51
|
+
response.value = stripData(response.value, endpoint.responseDto);
|
|
52
52
|
}
|
|
53
53
|
return response;
|
|
54
54
|
}
|
|
@@ -61,8 +61,8 @@ let DefaultHttpRequestHandler = class DefaultHttpRequestHandler extends Abstract
|
|
|
61
61
|
let params = {};
|
|
62
62
|
const mountedEndpointInfo = await this.getMountedEndpointInfo();
|
|
63
63
|
const info = mountedEndpointInfo.find((info) => {
|
|
64
|
-
const parsedParams = info.
|
|
65
|
-
match(info.
|
|
64
|
+
const parsedParams = info.method === method &&
|
|
65
|
+
match(info.mount, { decode: decodeURIComponent })(result.pathname || "/");
|
|
66
66
|
if (!parsedParams) {
|
|
67
67
|
return false;
|
|
68
68
|
}
|
|
@@ -83,15 +83,13 @@ let DefaultHttpRequestHandler = class DefaultHttpRequestHandler extends Abstract
|
|
|
83
83
|
params: params.params,
|
|
84
84
|
body: httpData.body,
|
|
85
85
|
cookies: httpData.cookies,
|
|
86
|
-
}, info
|
|
86
|
+
}, info);
|
|
87
87
|
const authInfo = await this.principalResolver.resolvePrincipal(request);
|
|
88
88
|
request.setAuthInfo(authInfo);
|
|
89
|
-
|
|
90
|
-
await this.authorizationProvider.authorize(request, info);
|
|
91
|
-
}
|
|
89
|
+
await this.authorizationProvider.authorize(request, info);
|
|
92
90
|
const mws = await this.getMiddleware();
|
|
93
91
|
for (const mw of mws) {
|
|
94
|
-
const next = await mw.intercept(request, response, info
|
|
92
|
+
const next = await mw.intercept(request, response, info);
|
|
95
93
|
if (!next) {
|
|
96
94
|
return response;
|
|
97
95
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { IPrincipal } from "../common/auth/IPrincipal";
|
|
1
|
+
import { type Constructor, AbstractModel, HttpMethod } from "@clairejs/core";
|
|
2
|
+
import { type UriMapperHandler } from "./file-upload/types";
|
|
3
|
+
import { type HttpResponse } from "./common/HttpResponse";
|
|
4
|
+
import { type IPrincipal } from "../common/auth/IPrincipal";
|
|
5
|
+
import { type AbstractHttpController } from "./controller/AbstractHttpController";
|
|
7
6
|
type HttpFunctionMethod<T> = (...args: any[]) => Promise<HttpResponse<T>>;
|
|
8
7
|
export declare const ApiDescription: (description: string) => (prototype: AbstractHttpController, propertyKey: string) => void;
|
|
9
8
|
export declare const Endpoint: (config: {
|
|
@@ -16,9 +15,6 @@ export declare const Del: (url: string) => (prototype: AbstractHttpController, p
|
|
|
16
15
|
export declare const Get: (url: string) => (prototype: AbstractHttpController, propertyKey: string, _descriptor: TypedPropertyDescriptor<HttpFunctionMethod<any>>) => void;
|
|
17
16
|
export declare const Head: (url: string) => (prototype: AbstractHttpController, propertyKey: string, _descriptor: TypedPropertyDescriptor<HttpFunctionMethod<any>>) => void;
|
|
18
17
|
export declare const ApiResponse: <T>(responseClass: Constructor<T>) => (prototype: AbstractHttpController, propertyKey: string, _descriptor: TypedPropertyDescriptor<HttpFunctionMethod<T>>) => void;
|
|
19
|
-
export declare const OpenAccess: () => (prototype: AbstractHttpController, propertyKey: string) => void;
|
|
20
|
-
export declare const TfaRequired: () => (prototype: AbstractHttpController, propertyKey: string) => void;
|
|
21
|
-
export declare const AccessCondition: (conditions: Constructor<AbstractAccessCondition>[]) => (prototype: AbstractHttpController, propertyKey: string) => void;
|
|
22
18
|
export declare const Body: () => (prototype: AbstractHttpController, propertyKey: string, paramIndex: number) => void;
|
|
23
19
|
export declare const Params: () => (prototype: AbstractHttpController, propertyKey: string, paramIndex: number) => void;
|
|
24
20
|
export declare const Queries: () => (prototype: AbstractHttpController, propertyKey: string, paramIndex: number) => void;
|
package/dist/http/decorators.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DataType, getObjectMetadata, HttpMethod, initFieldMetadata, } from "@clairejs/core";
|
|
2
2
|
export const ApiDescription = (description) => (prototype, propertyKey) => {
|
|
3
3
|
const endpointMetadata = initFieldMetadata(prototype, propertyKey);
|
|
4
4
|
endpointMetadata.description = description;
|
|
5
5
|
};
|
|
6
6
|
export const Endpoint = (config) => (prototype, propertyKey) => {
|
|
7
7
|
const endpointMetadata = initFieldMetadata(prototype, propertyKey);
|
|
8
|
-
endpointMetadata.
|
|
8
|
+
endpointMetadata.method = config.method;
|
|
9
9
|
//-- default to "/" if empty string is provided
|
|
10
|
-
endpointMetadata.
|
|
10
|
+
endpointMetadata.mount = config.url || "/";
|
|
11
11
|
};
|
|
12
12
|
const HttpMethodDecoratorFactory = (method) => (url) => (prototype, propertyKey, _descriptor) => Endpoint({ method, url })(prototype, propertyKey);
|
|
13
13
|
export const Post = HttpMethodDecoratorFactory(HttpMethod.POST);
|
|
@@ -18,42 +18,30 @@ export const Head = HttpMethodDecoratorFactory(HttpMethod.HEAD);
|
|
|
18
18
|
export const ApiResponse = (responseClass) => (prototype, propertyKey, _descriptor) => {
|
|
19
19
|
const endpointMetadata = initFieldMetadata(prototype, propertyKey);
|
|
20
20
|
if (responseClass === String) {
|
|
21
|
-
endpointMetadata.
|
|
21
|
+
endpointMetadata.responseDto = { id: "", primitiveType: DataType.STRING, fields: [] };
|
|
22
22
|
}
|
|
23
23
|
else if (responseClass === Number) {
|
|
24
|
-
endpointMetadata.
|
|
24
|
+
endpointMetadata.responseDto = { id: "", primitiveType: DataType.NUMBER, fields: [] };
|
|
25
25
|
}
|
|
26
26
|
else if (responseClass === Boolean) {
|
|
27
|
-
endpointMetadata.
|
|
27
|
+
endpointMetadata.responseDto = { id: "", primitiveType: DataType.BOOLEAN, fields: [] };
|
|
28
28
|
}
|
|
29
29
|
else {
|
|
30
|
-
endpointMetadata.
|
|
30
|
+
endpointMetadata.responseDto = getObjectMetadata(responseClass);
|
|
31
31
|
}
|
|
32
32
|
};
|
|
33
|
-
export const OpenAccess = () => (prototype, propertyKey) => {
|
|
34
|
-
const endpointMetadata = initFieldMetadata(prototype, propertyKey);
|
|
35
|
-
endpointMetadata.openAccess = true;
|
|
36
|
-
};
|
|
37
|
-
export const TfaRequired = () => (prototype, propertyKey) => {
|
|
38
|
-
const endpointMetadata = initFieldMetadata(prototype, propertyKey);
|
|
39
|
-
endpointMetadata.tfaRequired = true;
|
|
40
|
-
};
|
|
41
|
-
export const AccessCondition = (conditions) => (prototype, propertyKey) => {
|
|
42
|
-
const endpointMetadata = initFieldMetadata(prototype, propertyKey);
|
|
43
|
-
endpointMetadata.accessConditions = conditions;
|
|
44
|
-
};
|
|
45
33
|
const RequestDeco = (source) => (prototype, propertyKey, paramIndex) => {
|
|
46
34
|
const endpointMetadata = initFieldMetadata(prototype, propertyKey);
|
|
47
35
|
const paramClasses = Reflect.getMetadata("design:paramtypes", prototype, propertyKey) || [];
|
|
48
36
|
switch (source) {
|
|
49
37
|
case "body":
|
|
50
|
-
endpointMetadata.
|
|
38
|
+
endpointMetadata.bodyDto = getObjectMetadata(paramClasses[paramIndex]);
|
|
51
39
|
break;
|
|
52
40
|
case "params":
|
|
53
|
-
endpointMetadata.
|
|
41
|
+
endpointMetadata.paramDto = getObjectMetadata(paramClasses[paramIndex]);
|
|
54
42
|
break;
|
|
55
43
|
case "queries":
|
|
56
|
-
endpointMetadata.
|
|
44
|
+
endpointMetadata.queryDto = getObjectMetadata(paramClasses[paramIndex]);
|
|
57
45
|
break;
|
|
58
46
|
default:
|
|
59
47
|
break;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { AbstractLogger, CreateManyRequestBody, CreateManyResponseBody, GetManyQueries, GetManyResponseBody, UpdateManyBody, UpdateManyQueries, UpdateManyResponse } from "@clairejs/core";
|
|
2
|
-
import { IQueryProvider, ITransaction, QueryCondition } from "@clairejs/orm";
|
|
3
|
-
import { IPrincipal } from "../../common/auth/IPrincipal";
|
|
1
|
+
import { type AbstractLogger, type CreateManyRequestBody, type CreateManyResponseBody, type GetManyQueries, type GetManyResponseBody, type UpdateManyBody, type UpdateManyQueries, type UpdateManyResponse } from "@clairejs/core";
|
|
2
|
+
import { type IQueryProvider, type ITransaction, type QueryCondition } from "@clairejs/orm";
|
|
3
|
+
import { type IPrincipal } from "../../common/auth/IPrincipal";
|
|
4
4
|
export interface ICrudRepository<T> {
|
|
5
5
|
createMany({ principal, body, tx, logger, }: {
|
|
6
6
|
body: CreateManyRequestBody<T>;
|
package/dist/http/utils.d.ts
CHANGED
|
@@ -1,4 +1,2 @@
|
|
|
1
|
-
import { ApiInfoResponse } from "@clairejs/core";
|
|
2
|
-
import { HttpEndpoint } from "../common/request/HttpEndpoint";
|
|
3
|
-
export declare const getEndpointId: (endpoint: HttpEndpoint) => string;
|
|
1
|
+
import { type ApiInfoResponse } from "@clairejs/core";
|
|
4
2
|
export declare const getApiInfo: () => Promise<ApiInfoResponse>;
|
package/dist/http/utils.js
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getServiceProvider, pickData, ApiInfo, getObjectMetadata } from "@clairejs/core";
|
|
2
2
|
import { AbstractHttpRequestHandler } from "./controller/AbstractHttpRequestHandler";
|
|
3
3
|
import { AbstractServerSocketManager } from "../socket/AbstractServerSocketManager";
|
|
4
|
-
|
|
5
|
-
return `${endpoint.httpMethod}:${endpoint.mount}`;
|
|
6
|
-
};
|
|
4
|
+
const fields = (getObjectMetadata(ApiInfo)?.fields || []).map((f) => f.name);
|
|
7
5
|
export const getApiInfo = async () => {
|
|
8
6
|
const injector = getServiceProvider().getInjector();
|
|
9
7
|
const httpHandler = injector.resolveOptional(AbstractHttpRequestHandler);
|
|
@@ -12,21 +10,6 @@ export const getApiInfo = async () => {
|
|
|
12
10
|
const httpInfo = httpHandler ? await httpHandler.getMountedEndpointInfo() : [];
|
|
13
11
|
const socketInfo = socketManager ? await socketManager.getMountedEndpointInfo() : [];
|
|
14
12
|
return {
|
|
15
|
-
|
|
16
|
-
id: getEndpointId(endpointInfo.endpoint),
|
|
17
|
-
description: endpointInfo.endpointMetadata.description,
|
|
18
|
-
name: endpointInfo.endpointMetadata.displayName || endpointInfo.endpointMetadata.name,
|
|
19
|
-
openAccess: !!endpointInfo.endpointMetadata.openAccess,
|
|
20
|
-
permissionGroup: endpointInfo.endpointMetadata.permissionGroup || "",
|
|
21
|
-
accessConditions: endpointInfo.endpointMetadata.accessConditions?.map((ac) => injector.resolve(ac).getConditionMetadata()) || [],
|
|
22
|
-
readOnly: endpointInfo.endpointMetadata.httpMethod === HttpMethod.GET,
|
|
23
|
-
tfaRequired: !!endpointInfo.endpointMetadata.tfaRequired,
|
|
24
|
-
method: endpointInfo.endpointMetadata.httpMethod,
|
|
25
|
-
mount: endpointInfo.endpoint.mount || "",
|
|
26
|
-
paramDto: endpointInfo.endpointMetadata.paramsValidationDto,
|
|
27
|
-
queryDto: endpointInfo.endpointMetadata.queriesValidationDto,
|
|
28
|
-
bodyDto: endpointInfo.endpointMetadata.bodyValidationDto,
|
|
29
|
-
responseDto: endpointInfo.endpointMetadata.responseValidationDto,
|
|
30
|
-
})),
|
|
13
|
+
apis: [...httpInfo, ...socketInfo].map((metadata) => pickData(metadata, fields)),
|
|
31
14
|
};
|
|
32
15
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
export * from "./common/FileOperation";
|
|
2
2
|
export * from "./common/auth/AbstractPrincipalResolver";
|
|
3
3
|
export * from "./common/auth/IPrincipal";
|
|
4
|
-
export * from "./common/request/
|
|
5
|
-
export * from "./common/request/HttpEndpoint";
|
|
6
|
-
export * from "./common/request/EndpointMetadata";
|
|
4
|
+
export * from "./common/request/endpoint-metadata";
|
|
7
5
|
export * from "./common/request/RequestOptions";
|
|
8
6
|
export * from "./common/AbstractController";
|
|
9
7
|
export * from "./common/ControllerMetadata";
|
|
@@ -17,9 +15,6 @@ export * from "./http/controller/CrudHttpController";
|
|
|
17
15
|
export * from "./http/controller/AbstractHttpRequestHandler";
|
|
18
16
|
export * from "./http/controller/AbstractHttpMiddleware";
|
|
19
17
|
export * from "./http/security/cors";
|
|
20
|
-
export * from "./http/security/AbstractAccessCondition";
|
|
21
|
-
export * from "./http/security/access-conditions/FilterModelFieldAccessCondition";
|
|
22
|
-
export * from "./http/security/access-conditions/MaximumQueryLimit";
|
|
23
18
|
export * from "./http/auth/AbstractHttpAuthorizer";
|
|
24
19
|
export * from "./http/repository/ModelRepository";
|
|
25
20
|
export * from "./http/repository/DtoRepository";
|
package/dist/index.js
CHANGED
|
@@ -2,9 +2,7 @@
|
|
|
2
2
|
export * from "./common/FileOperation";
|
|
3
3
|
export * from "./common/auth/AbstractPrincipalResolver";
|
|
4
4
|
export * from "./common/auth/IPrincipal";
|
|
5
|
-
export * from "./common/request/
|
|
6
|
-
export * from "./common/request/HttpEndpoint";
|
|
7
|
-
export * from "./common/request/EndpointMetadata";
|
|
5
|
+
export * from "./common/request/endpoint-metadata";
|
|
8
6
|
export * from "./common/request/RequestOptions";
|
|
9
7
|
export * from "./common/AbstractController";
|
|
10
8
|
export * from "./common/ControllerMetadata";
|
|
@@ -19,9 +17,6 @@ export * from "./http/controller/CrudHttpController";
|
|
|
19
17
|
export * from "./http/controller/AbstractHttpRequestHandler";
|
|
20
18
|
export * from "./http/controller/AbstractHttpMiddleware";
|
|
21
19
|
export * from "./http/security/cors";
|
|
22
|
-
export * from "./http/security/AbstractAccessCondition";
|
|
23
|
-
export * from "./http/security/access-conditions/FilterModelFieldAccessCondition";
|
|
24
|
-
export * from "./http/security/access-conditions/MaximumQueryLimit";
|
|
25
20
|
export * from "./http/auth/AbstractHttpAuthorizer";
|
|
26
21
|
export * from "./http/repository/ModelRepository";
|
|
27
22
|
export * from "./http/repository/DtoRepository";
|
|
@@ -2,8 +2,8 @@ import { AbstractLogger, SocketMessage } from "@clairejs/core";
|
|
|
2
2
|
import Redis from "ioredis";
|
|
3
3
|
import { SocketData } from "../common/request/SocketData";
|
|
4
4
|
import { IPrincipal } from "../common/auth/IPrincipal";
|
|
5
|
+
import { EndpointMetadata } from "../common/request/endpoint-metadata";
|
|
5
6
|
import { AbstractPrincipalResolver } from "../common/auth/AbstractPrincipalResolver";
|
|
6
|
-
import { MountedEndpointInfo } from "../common/request/MountedEndpointInfo";
|
|
7
7
|
import { AbstractRequestAuthorizer } from "../http/auth/AbstractHttpAuthorizer";
|
|
8
8
|
import { AbstractSocketConnectionHandler } from "./AbstractSocketConnectionHandler";
|
|
9
9
|
import { AbstractServerSocket } from "./AbstractServerSocket";
|
|
@@ -42,5 +42,5 @@ export declare abstract class AbstractServerSocketManager {
|
|
|
42
42
|
removeSocket(socketId: string, _physicRemove?: boolean): Promise<void>;
|
|
43
43
|
abstract getById(socketId: string): Promise<AbstractServerSocket | undefined>;
|
|
44
44
|
handle(socketData: SocketData): Promise<void>;
|
|
45
|
-
getMountedEndpointInfo(): Promise<
|
|
45
|
+
getMountedEndpointInfo(): Promise<EndpointMetadata[]>;
|
|
46
46
|
}
|
|
@@ -1,53 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { AccessConditionValueType, DataType, Errors, getObjectMetadata, getServiceProvider, MessageType, Register, SocketMethod, } from "@clairejs/core";
|
|
8
|
-
import { AbstractAccessCondition } from "../http/security/AbstractAccessCondition";
|
|
1
|
+
import { DataType, Errors, getServiceProvider, MessageType, SocketMethod, } from "@clairejs/core";
|
|
9
2
|
import { HttpRequest } from "../http/common/HttpRequest";
|
|
10
3
|
import { AbstractSocketConnectionHandler } from "./AbstractSocketConnectionHandler";
|
|
11
4
|
import { AbstractSocketController } from "./AbstractSocketController";
|
|
12
5
|
const SOCKET_ACTION_HEADER = "x-socket-action";
|
|
13
6
|
const SOCKET_ACTION_READ = "read";
|
|
14
7
|
const SOCKET_ACTION_WRITE = "write";
|
|
15
|
-
let SocketReadCondition = class SocketReadCondition extends AbstractAccessCondition {
|
|
16
|
-
async resolveConditionValue(request) {
|
|
17
|
-
return request.headers[SOCKET_ACTION_HEADER] === SOCKET_ACTION_READ;
|
|
18
|
-
}
|
|
19
|
-
async validate(conditionValue) {
|
|
20
|
-
return !!conditionValue;
|
|
21
|
-
}
|
|
22
|
-
getConditionMetadata() {
|
|
23
|
-
return {
|
|
24
|
-
name: "disable_write",
|
|
25
|
-
description: "Disable send message to channel",
|
|
26
|
-
valueType: AccessConditionValueType.BOOLEAN,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
SocketReadCondition = __decorate([
|
|
31
|
-
Register()
|
|
32
|
-
], SocketReadCondition);
|
|
33
|
-
let SocketWriteCondition = class SocketWriteCondition extends AbstractAccessCondition {
|
|
34
|
-
async resolveConditionValue(request) {
|
|
35
|
-
return request.headers[SOCKET_ACTION_HEADER] === SOCKET_ACTION_WRITE;
|
|
36
|
-
}
|
|
37
|
-
async validate(conditionValue) {
|
|
38
|
-
return !!conditionValue;
|
|
39
|
-
}
|
|
40
|
-
getConditionMetadata() {
|
|
41
|
-
return {
|
|
42
|
-
name: "disable_read",
|
|
43
|
-
description: "Disable receive message from channel",
|
|
44
|
-
valueType: AccessConditionValueType.BOOLEAN,
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
SocketWriteCondition = __decorate([
|
|
49
|
-
Register()
|
|
50
|
-
], SocketWriteCondition);
|
|
51
8
|
export class AbstractServerSocketManager {
|
|
52
9
|
requireAuthentication;
|
|
53
10
|
logger;
|
|
@@ -157,9 +114,9 @@ export class AbstractServerSocketManager {
|
|
|
157
114
|
//-- notify all channels
|
|
158
115
|
this.logger.debug("Notify channels");
|
|
159
116
|
for (const channelInfo of socket.getChannelsInfo()) {
|
|
160
|
-
const currentEndpoint = mountedEndpoints.find((e) => e.
|
|
117
|
+
const currentEndpoint = mountedEndpoints.find((e) => e.mount === channelInfo.name);
|
|
161
118
|
if (currentEndpoint) {
|
|
162
|
-
currentEndpoint.
|
|
119
|
+
currentEndpoint.controller.onChannelLeave(socket);
|
|
163
120
|
}
|
|
164
121
|
}
|
|
165
122
|
this.logger.debug("Calling disconnection handler");
|
|
@@ -206,7 +163,7 @@ export class AbstractServerSocketManager {
|
|
|
206
163
|
let canSend = false;
|
|
207
164
|
let canReceive = false;
|
|
208
165
|
const mountedEndpoints = await this.getMountedEndpointInfo();
|
|
209
|
-
const currentEndpoint = mountedEndpoints.find((e) => e.
|
|
166
|
+
const currentEndpoint = mountedEndpoints.find((e) => e.mount === channel);
|
|
210
167
|
if (!currentEndpoint) {
|
|
211
168
|
continue;
|
|
212
169
|
}
|
|
@@ -215,7 +172,7 @@ export class AbstractServerSocketManager {
|
|
|
215
172
|
method: SocketMethod.MESSAGE,
|
|
216
173
|
pathName: channel,
|
|
217
174
|
headers: { [SOCKET_ACTION_HEADER]: SOCKET_ACTION_READ },
|
|
218
|
-
}, currentEndpoint
|
|
175
|
+
}, currentEndpoint);
|
|
219
176
|
request.setAuthInfo(clientSocket.getAuthInfo());
|
|
220
177
|
await this.requestAuthorizer.authorize(request, currentEndpoint);
|
|
221
178
|
canReceive = true;
|
|
@@ -228,7 +185,7 @@ export class AbstractServerSocketManager {
|
|
|
228
185
|
method: SocketMethod.MESSAGE,
|
|
229
186
|
pathName: channel,
|
|
230
187
|
headers: { [SOCKET_ACTION_HEADER]: SOCKET_ACTION_WRITE },
|
|
231
|
-
}, currentEndpoint
|
|
188
|
+
}, currentEndpoint);
|
|
232
189
|
request.setAuthInfo(clientSocket.getAuthInfo());
|
|
233
190
|
await this.requestAuthorizer.authorize(request, currentEndpoint);
|
|
234
191
|
canSend = true;
|
|
@@ -258,7 +215,7 @@ export class AbstractServerSocketManager {
|
|
|
258
215
|
type: MessageType.CHANNEL_JOIN,
|
|
259
216
|
data: channelsInfo.map((c) => c.name),
|
|
260
217
|
}),
|
|
261
|
-
...endpoints.map((endpoint) => endpoint.
|
|
218
|
+
...endpoints.map((endpoint) => endpoint.controller.onChannelJoin(clientSocket)),
|
|
262
219
|
]);
|
|
263
220
|
}
|
|
264
221
|
}
|
|
@@ -269,11 +226,11 @@ export class AbstractServerSocketManager {
|
|
|
269
226
|
//-- remove channels from socket
|
|
270
227
|
const mountedEndpoints = await this.getMountedEndpointInfo();
|
|
271
228
|
Promise.all(channels.map((channel) => () => {
|
|
272
|
-
const currentEndpoint = mountedEndpoints.find((e) => e.
|
|
229
|
+
const currentEndpoint = mountedEndpoints.find((e) => e.mount === channel);
|
|
273
230
|
if (!currentEndpoint) {
|
|
274
231
|
return;
|
|
275
232
|
}
|
|
276
|
-
return currentEndpoint.
|
|
233
|
+
return currentEndpoint.controller.onChannelLeave(clientSocket);
|
|
277
234
|
}));
|
|
278
235
|
//-- remove socket from channels
|
|
279
236
|
await this.removeSocketFromChannel(clientSocket.getId(), channels);
|
|
@@ -291,9 +248,9 @@ export class AbstractServerSocketManager {
|
|
|
291
248
|
.find((info) => info.name === channel && info.clientToServerAllowed);
|
|
292
249
|
if (allowed) {
|
|
293
250
|
const mountedEndpoints = await this.getMountedEndpointInfo();
|
|
294
|
-
const currentEndpoint = mountedEndpoints.find((e) => e.
|
|
251
|
+
const currentEndpoint = mountedEndpoints.find((e) => e.mount === channel);
|
|
295
252
|
if (currentEndpoint) {
|
|
296
|
-
const result = await currentEndpoint.
|
|
253
|
+
const result = await currentEndpoint.controller.onMessage(clientSocket, data);
|
|
297
254
|
if (result !== false) {
|
|
298
255
|
//-- broadcast
|
|
299
256
|
this.logger.debug("broadcasting to channel", channel, data);
|
|
@@ -325,23 +282,16 @@ export class AbstractServerSocketManager {
|
|
|
325
282
|
const socketController = injector.resolveMultiple(AbstractSocketController);
|
|
326
283
|
await injector.initInstances();
|
|
327
284
|
this.mountedEndpointInfo = socketController.map((controller) => {
|
|
328
|
-
const controllerMetadata = getObjectMetadata(controller.constructor);
|
|
329
285
|
return {
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
permissionGroup: controllerMetadata.permissionGroup,
|
|
340
|
-
dataType: DataType.OBJECT,
|
|
341
|
-
url: controller.getChannelName(),
|
|
342
|
-
name: controller.getChannelName(),
|
|
343
|
-
accessConditions: [SocketReadCondition, SocketWriteCondition],
|
|
344
|
-
},
|
|
286
|
+
id: `${SocketMethod.MESSAGE}:${controller.getChannelName()}`,
|
|
287
|
+
readOnly: false,
|
|
288
|
+
controller: socketController,
|
|
289
|
+
method: SocketMethod.MESSAGE,
|
|
290
|
+
mount: controller.getChannelName(),
|
|
291
|
+
handlerFunctionName: controller.onMessage.name,
|
|
292
|
+
description: "Send / Receive message to / from channel",
|
|
293
|
+
name: controller.getChannelName(),
|
|
294
|
+
dataType: DataType.OBJECT,
|
|
345
295
|
};
|
|
346
296
|
});
|
|
347
297
|
}
|
|
@@ -7,7 +7,6 @@ export declare abstract class AbstractSocketController extends AbstractControlle
|
|
|
7
7
|
/**
|
|
8
8
|
* Handle the message sent to this channel
|
|
9
9
|
* @param socket the socket sending message
|
|
10
|
-
* @param data the data payload being sent
|
|
11
10
|
* @returns return false to prevent message broadcast
|
|
12
11
|
*/
|
|
13
12
|
onMessage(_socket: IServerSocket, _message: any): Promise<boolean | void>;
|
|
@@ -5,7 +5,6 @@ export class AbstractSocketController extends AbstractController {
|
|
|
5
5
|
/**
|
|
6
6
|
* Handle the message sent to this channel
|
|
7
7
|
* @param socket the socket sending message
|
|
8
|
-
* @param data the data payload being sent
|
|
9
8
|
* @returns return false to prevent message broadcast
|
|
10
9
|
*/
|
|
11
10
|
async onMessage(_socket, _message) { }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbstractLogger, ClaireApp } from "@clairejs/core";
|
|
2
|
-
import { AbstractHttpRequestHandler } from "../http/controller/AbstractHttpRequestHandler";
|
|
3
|
-
import { AbstractServerSocketManager } from "../socket/AbstractServerSocketManager";
|
|
2
|
+
import { type AbstractHttpRequestHandler } from "../http/controller/AbstractHttpRequestHandler";
|
|
3
|
+
import { type AbstractServerSocketManager } from "../socket/AbstractServerSocketManager";
|
|
4
4
|
export declare class ClaireServer extends ClaireApp {
|
|
5
5
|
protected readonly logger: AbstractLogger;
|
|
6
6
|
protected readonly httpRequestHandler?: AbstractHttpRequestHandler | undefined;
|
|
@@ -8,6 +8,5 @@ export declare class ClaireServer extends ClaireApp {
|
|
|
8
8
|
private booted;
|
|
9
9
|
constructor(logger: AbstractLogger, httpRequestHandler?: AbstractHttpRequestHandler | undefined, socketManager?: AbstractServerSocketManager | undefined);
|
|
10
10
|
init(): Promise<void>;
|
|
11
|
-
exit(): void;
|
|
12
11
|
private stop;
|
|
13
12
|
}
|
|
@@ -9,9 +9,6 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
9
9
|
};
|
|
10
10
|
import { AbstractLogger, ClaireApp, LogContext, getGlobalStore } from "@clairejs/core";
|
|
11
11
|
import { ExitCode } from "../common/constants";
|
|
12
|
-
import { AbstractHttpRequestHandler } from "../http/controller/AbstractHttpRequestHandler";
|
|
13
|
-
import { AbstractServerSocketManager } from "../socket/AbstractServerSocketManager";
|
|
14
|
-
import { getEndpointId } from "../http/utils";
|
|
15
12
|
let ClaireServer = class ClaireServer extends ClaireApp {
|
|
16
13
|
logger;
|
|
17
14
|
httpRequestHandler;
|
|
@@ -38,7 +35,7 @@ let ClaireServer = class ClaireServer extends ClaireApp {
|
|
|
38
35
|
}
|
|
39
36
|
//-- save mounted endpoint info in server store to prevent circular dependency when resolving http request handler in controller
|
|
40
37
|
for (const endpoint of mountedEndpointInfo) {
|
|
41
|
-
this.logger.info(`Mounting: ${
|
|
38
|
+
this.logger.info(`Mounting: ${endpoint.method}:${endpoint.mount}`);
|
|
42
39
|
}
|
|
43
40
|
getGlobalStore().mountedEndpointInfo = mountedEndpointInfo;
|
|
44
41
|
this.logger.debug("Claire server initing");
|
|
@@ -60,9 +57,6 @@ let ClaireServer = class ClaireServer extends ClaireApp {
|
|
|
60
57
|
});
|
|
61
58
|
this.booted = true;
|
|
62
59
|
}
|
|
63
|
-
exit() {
|
|
64
|
-
super.exit();
|
|
65
|
-
}
|
|
66
60
|
stop(code) {
|
|
67
61
|
this.logger.debug("Server is shutting down");
|
|
68
62
|
this.exit();
|
|
@@ -71,8 +65,6 @@ let ClaireServer = class ClaireServer extends ClaireApp {
|
|
|
71
65
|
};
|
|
72
66
|
ClaireServer = __decorate([
|
|
73
67
|
LogContext(),
|
|
74
|
-
__metadata("design:paramtypes", [AbstractLogger,
|
|
75
|
-
AbstractHttpRequestHandler,
|
|
76
|
-
AbstractServerSocketManager])
|
|
68
|
+
__metadata("design:paramtypes", [AbstractLogger, Function, Function])
|
|
77
69
|
], ClaireServer);
|
|
78
70
|
export { ClaireServer };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CoreGlobalStore } from "@clairejs/core";
|
|
2
|
-
import {
|
|
2
|
+
import { EndpointMetadata } from "../common/request/endpoint-metadata";
|
|
3
3
|
export interface ServerGlobalStore extends CoreGlobalStore {
|
|
4
|
-
mountedEndpointInfo?:
|
|
4
|
+
mountedEndpointInfo?: EndpointMetadata[];
|
|
5
5
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clairejs/server",
|
|
3
|
-
"version": "3.17.
|
|
3
|
+
"version": "3.17.1",
|
|
4
4
|
"description": "Claire server NodeJs framework written in Typescript.",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -16,10 +16,12 @@
|
|
|
16
16
|
"license": "ISC",
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"aws-sdk": "^2.841.0",
|
|
19
|
+
"axios": "^0.21.4",
|
|
19
20
|
"cookie-parser": "^1.4.6",
|
|
20
21
|
"cors": "^2.8.5",
|
|
21
22
|
"express": "^4.17.1",
|
|
22
23
|
"express-fileupload": "^1.2.1",
|
|
24
|
+
"ioredis": "^5.2.0",
|
|
23
25
|
"node-cron": "^3.0.1",
|
|
24
26
|
"node-schedule": "^2.1.0",
|
|
25
27
|
"parseurl": "^1.3.3",
|
|
@@ -28,12 +30,10 @@
|
|
|
28
30
|
"randomstring": "^1.2.2",
|
|
29
31
|
"redlock": "^5.0.0-beta.2",
|
|
30
32
|
"reflect-metadata": "^0.1.13",
|
|
31
|
-
"ws": "^7.5.5"
|
|
32
|
-
"ioredis": "^5.2.0",
|
|
33
|
-
"axios": "^0.21.4"
|
|
33
|
+
"ws": "^7.5.5"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"@clairejs/core": "^3.
|
|
36
|
+
"@clairejs/core": "^3.7.1",
|
|
37
37
|
"@clairejs/orm": "^3.11.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { Constructor, DtoMetadata, HttpMethod, SocketMethod, ObjectFieldMetadata } from "@clairejs/core";
|
|
2
|
-
import { RequestDataSource } from "./types";
|
|
3
|
-
import { AbstractAccessCondition } from "../../http/security/AbstractAccessCondition";
|
|
4
|
-
export interface EndpointMetadata extends ObjectFieldMetadata {
|
|
5
|
-
/**
|
|
6
|
-
* Basic HTTP information, name property is handler function name.
|
|
7
|
-
*/
|
|
8
|
-
httpMethod: HttpMethod | SocketMethod;
|
|
9
|
-
url: string;
|
|
10
|
-
/**
|
|
11
|
-
* User-friendly display name of endpoint.
|
|
12
|
-
*/
|
|
13
|
-
displayName?: string;
|
|
14
|
-
bodyValidationDto?: DtoMetadata;
|
|
15
|
-
queriesValidationDto?: DtoMetadata;
|
|
16
|
-
paramsValidationDto?: DtoMetadata;
|
|
17
|
-
responseValidationDto?: DtoMetadata;
|
|
18
|
-
params?: {
|
|
19
|
-
[index: number]: {
|
|
20
|
-
source?: RequestDataSource;
|
|
21
|
-
diClass?: Constructor<any>;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* This endpoint requires tfa
|
|
26
|
-
*/
|
|
27
|
-
tfaRequired?: boolean;
|
|
28
|
-
/**
|
|
29
|
-
* Allow public access to this endpoint.
|
|
30
|
-
*/
|
|
31
|
-
openAccess?: boolean;
|
|
32
|
-
/**
|
|
33
|
-
* Metadata of access condition to allow a conditional access to the endpoint.
|
|
34
|
-
*/
|
|
35
|
-
accessConditions?: Constructor<AbstractAccessCondition>[];
|
|
36
|
-
/**
|
|
37
|
-
* Group of permission of this endpoint.
|
|
38
|
-
*/
|
|
39
|
-
permissionGroup?: string;
|
|
40
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { AccessConditionMetadata } from "@clairejs/core";
|
|
2
|
-
import { HttpRequest } from "../common/HttpRequest";
|
|
3
|
-
export declare abstract class AbstractAccessCondition<T = any> {
|
|
4
|
-
abstract resolveConditionValue(request: HttpRequest): Promise<T>;
|
|
5
|
-
abstract validate(conditionValue: T, permittedConditionValue: any): Promise<boolean>;
|
|
6
|
-
abstract getConditionMetadata(): AccessConditionMetadata;
|
|
7
|
-
}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { Constructor } from "@clairejs/core";
|
|
2
|
-
import { HttpRequest } from "../../common/HttpRequest";
|
|
3
|
-
import { AbstractAccessCondition } from "../AbstractAccessCondition";
|
|
4
|
-
export declare const FilterModelFieldAccessCondition: <T extends Constructor<any>>(model: T, name: string, requestedConditionValueResolver: (request: HttpRequest) => string[] | undefined) => Constructor<AbstractAccessCondition<string[] | undefined>>;
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { AccessConditionValueType, getObjectMetadata, Register, } from "@clairejs/core";
|
|
8
|
-
import { AbstractAccessCondition } from "../AbstractAccessCondition";
|
|
9
|
-
export const FilterModelFieldAccessCondition = (model, name, requestedConditionValueResolver) => {
|
|
10
|
-
let _ = class _ extends AbstractAccessCondition {
|
|
11
|
-
async resolveConditionValue(request) {
|
|
12
|
-
return requestedConditionValueResolver(request);
|
|
13
|
-
}
|
|
14
|
-
getConditionMetadata() {
|
|
15
|
-
return {
|
|
16
|
-
name,
|
|
17
|
-
valueType: AccessConditionValueType.CHOICES,
|
|
18
|
-
valueConstraint: getObjectMetadata(model).fields.map((f) => f.name),
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
async validate(requestedConditionValue, permittedConditionValue) {
|
|
22
|
-
return (!!requestedConditionValue &&
|
|
23
|
-
requestedConditionValue.every((value) => permittedConditionValue.includes(value)));
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
_ = __decorate([
|
|
27
|
-
Register()
|
|
28
|
-
], _);
|
|
29
|
-
return _;
|
|
30
|
-
};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { AccessConditionMetadata } from "@clairejs/core";
|
|
2
|
-
import { HttpRequest } from "../../common/HttpRequest";
|
|
3
|
-
import { AbstractAccessCondition } from "../AbstractAccessCondition";
|
|
4
|
-
export declare class MaximumQueryLimit extends AbstractAccessCondition {
|
|
5
|
-
resolveConditionValue(request: HttpRequest): Promise<any>;
|
|
6
|
-
validate(conditionValue: number, permittedConditionValue: number): Promise<boolean>;
|
|
7
|
-
getConditionMetadata(): AccessConditionMetadata;
|
|
8
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
import { AccessConditionValueType, Register } from "@clairejs/core";
|
|
8
|
-
import { AbstractAccessCondition } from "../AbstractAccessCondition";
|
|
9
|
-
let MaximumQueryLimit = class MaximumQueryLimit extends AbstractAccessCondition {
|
|
10
|
-
async resolveConditionValue(request) {
|
|
11
|
-
let limit = request.getQuery().limit;
|
|
12
|
-
if (limit) {
|
|
13
|
-
limit = parseInt(limit);
|
|
14
|
-
}
|
|
15
|
-
return limit || 0;
|
|
16
|
-
}
|
|
17
|
-
async validate(conditionValue, permittedConditionValue) {
|
|
18
|
-
return conditionValue > 0 && conditionValue <= permittedConditionValue;
|
|
19
|
-
}
|
|
20
|
-
getConditionMetadata() {
|
|
21
|
-
return {
|
|
22
|
-
name: "maximum_query_limit",
|
|
23
|
-
valueType: AccessConditionValueType.NUMBER,
|
|
24
|
-
valueConstraint: JSON.stringify({ min: 1 }),
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
MaximumQueryLimit = __decorate([
|
|
29
|
-
Register()
|
|
30
|
-
], MaximumQueryLimit);
|
|
31
|
-
export { MaximumQueryLimit };
|
|
File without changes
|