@clairejs/server 3.16.19 → 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.
Files changed (47) hide show
  1. package/README.md +5 -0
  2. package/dist/common/ControllerMetadata.d.ts +2 -2
  3. package/dist/common/request/endpoint-metadata.d.ts +12 -0
  4. package/dist/http/auth/AbstractHttpAuthorizer.d.ts +2 -2
  5. package/dist/http/common/HttpRequest.d.ts +1 -1
  6. package/dist/http/common/HttpRequest.js +7 -8
  7. package/dist/http/controller/AbstractHttpController.d.ts +2 -2
  8. package/dist/http/controller/AbstractHttpController.js +2 -2
  9. package/dist/http/controller/AbstractHttpMiddleware.d.ts +1 -1
  10. package/dist/http/controller/AbstractHttpRequestHandler.d.ts +8 -8
  11. package/dist/http/controller/AbstractHttpRequestHandler.js +14 -22
  12. package/dist/http/controller/CrudHttpController.d.ts +6 -6
  13. package/dist/http/controller/CrudHttpController.js +42 -84
  14. package/dist/http/controller/DefaultHttpRequestHandler.d.ts +2 -2
  15. package/dist/http/controller/DefaultHttpRequestHandler.js +9 -11
  16. package/dist/http/decorators.d.ts +5 -9
  17. package/dist/http/decorators.js +10 -22
  18. package/dist/http/repository/ICrudRepository.d.ts +3 -3
  19. package/dist/http/utils.d.ts +1 -3
  20. package/dist/http/utils.js +3 -20
  21. package/dist/index.d.ts +1 -6
  22. package/dist/index.js +1 -6
  23. package/dist/services/AbstractFileService.d.ts +2 -0
  24. package/dist/services/implementations/LocalFileService.d.ts +2 -0
  25. package/dist/services/implementations/LocalFileService.js +9 -0
  26. package/dist/services/implementations/S3FileService.d.ts +3 -1
  27. package/dist/services/implementations/S3FileService.js +22 -5
  28. package/dist/socket/AbstractServerSocketManager.d.ts +2 -2
  29. package/dist/socket/AbstractServerSocketManager.js +20 -70
  30. package/dist/socket/AbstractSocketController.d.ts +0 -1
  31. package/dist/socket/AbstractSocketController.js +0 -1
  32. package/dist/system/ClaireServer.d.ts +2 -3
  33. package/dist/system/ClaireServer.js +2 -10
  34. package/dist/system/ServerGlobalStore.d.ts +2 -2
  35. package/package.json +5 -5
  36. package/dist/common/request/EndpointMetadata.d.ts +0 -40
  37. package/dist/common/request/HttpEndpoint.d.ts +0 -7
  38. package/dist/common/request/HttpEndpoint.js +0 -1
  39. package/dist/common/request/MountedEndpointInfo.d.ts +0 -6
  40. package/dist/common/request/MountedEndpointInfo.js +0 -1
  41. package/dist/http/security/AbstractAccessCondition.d.ts +0 -7
  42. package/dist/http/security/AbstractAccessCondition.js +0 -2
  43. package/dist/http/security/access-conditions/FilterModelFieldAccessCondition.d.ts +0 -4
  44. package/dist/http/security/access-conditions/FilterModelFieldAccessCondition.js +0 -30
  45. package/dist/http/security/access-conditions/MaximumQueryLimit.d.ts +0 -8
  46. package/dist/http/security/access-conditions/MaximumQueryLimit.js +0 -31
  47. /package/dist/common/request/{EndpointMetadata.js → endpoint-metadata.js} +0 -0
package/README.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## Change Log
2
2
 
3
+ #### 3.17.1:
4
+
5
+ - refactor EndpointMetadata, remove MountedEndpointInfo
6
+ - add putFile in AbstractFileService
7
+
3
8
  #### 3.16.19:
4
9
 
5
10
  - fix dependency
@@ -1,5 +1,5 @@
1
- import { ObjectMetadata } from "@clairejs/core";
2
- import { EndpointMetadata } from "./request/EndpointMetadata";
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 { MountedEndpointInfo } from "../../common/request/MountedEndpointInfo";
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: MountedEndpointInfo): Promise<void>;
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/EndpointMetadata";
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?.paramsValidationDto && !this.params.validated) {
50
- this.params.data = validateData(this.params.data, this.endpointMetadata.paramsValidationDto);
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?.queriesValidationDto && !this.query.validated) {
57
- this.query.data = validateData(this.jsonParsing(this.query.data, this.endpointMetadata.queriesValidationDto), this.endpointMetadata.queriesValidationDto);
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.httpMethod === HttpMethod.POST ||
65
- this.endpointMetadata.httpMethod === HttpMethod.PUT) &&
66
- this.endpointMetadata?.bodyValidationDto) {
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/EndpointMetadata";
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.httpMethod || metadata.openAccess !== undefined || !!metadata.accessConditions;
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, permissionGroup: controllerMetadata.permissionGroup }));
19
+ .map((f) => ({ ...f, apiGroup: controllerMetadata.permissionGroup }));
20
20
  }
21
21
  }
@@ -1,4 +1,4 @@
1
- import { EndpointMetadata } from "../../common/request/EndpointMetadata";
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 { MountedEndpointInfo } from "../../common/request/MountedEndpointInfo";
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 resolverMountPoint(controllerMetadata: ControllerMetadata, mappingUrls: string[]): string;
15
- getMountedEndpointInfo(): Promise<MountedEndpointInfo[]>;
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
- resolverMountPoint(controllerMetadata, mappingUrls) {
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
- for (const endpointMetadata of allEndpointMetadata) {
34
- const endpoint = {
35
- mount: endpointMetadata.httpMethod === SocketMethod.MESSAGE
36
- ? endpointMetadata.url
37
- : this.resolverMountPoint(controllerMetadata, [
38
- this.mountPoint || "/",
39
- endpointMetadata.url,
40
- ]),
41
- httpMethod: endpointMetadata.httpMethod,
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
- result.push({
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.endpoint.mount === endpointInfo.endpoint.mount &&
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: ${getEndpointId(overridingEndpoint.endpoint)} of ${overridingEndpoint.endpoint.controller?.constructor.name}:${overridingEndpoint.endpoint.handlerFunctionName}`, `Ignore ${getEndpointId(endpointInfo.endpoint)} of ${endpointInfo.endpoint.controller?.constructor.name}:${endpointInfo.endpoint.handlerFunctionName}`);
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, UpdateManyResponse, Identifiable, Constructor, ModelMetadata } from "@clairejs/core";
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/EndpointMetadata";
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 { getObjectMetadata, HttpMethod, getServiceProvider, leanData, getCreateManyBodyValidator, getCreateManyResponseValidator, getGetManyQueryValidator, getGetManyResponseValidator, getUpdateManyQueryValidator, getUpdateManyBodyValidator, getUpdateManyResponseValidator, uniqueReducer, omitData, getUpdateRecordsQueryValidator, getUpdateRecordsBodyValidator, } from "@clairejs/core";
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 { AccessCondition, ApiDescription, Raw } from "../decorators";
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.httpMethod = HttpMethod.POST;
52
- endpointMetadata.url = this.getMountedUrl();
53
- endpointMetadata.name = CrudHttpController.prototype.createMany.name;
54
- endpointMetadata.displayName = "createMany" + this.model.name;
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.bodyValidationDto = getCreateManyBodyValidator(this.modelMetadata);
53
+ endpointMetadata.bodyDto = getCreateManyBodyValidator(this.modelMetadata);
57
54
  //-- response dto ------------------------------------
58
- endpointMetadata.responseValidationDto = getCreateManyResponseValidator(this.modelMetadata);
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.httpMethod = HttpMethod.GET;
70
- endpointMetadata.url = this.getMountedUrl();
71
- endpointMetadata.name = CrudHttpController.prototype.getMany.name;
72
- endpointMetadata.displayName = "getAll" + this.model.name;
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.queriesValidationDto = getGetManyQueryValidator(this.modelMetadata);
70
+ endpointMetadata.queryDto = getGetManyQueryValidator(this.modelMetadata);
75
71
  //-- response dto ------------------------------------
76
- endpointMetadata.responseValidationDto = getGetManyResponseValidator(this.modelMetadata);
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.httpMethod = HttpMethod.PUT;
91
- endpointMetadata.url = this.getMountedUrl();
92
- endpointMetadata.name = CrudHttpController.prototype.updateMany.name;
93
- endpointMetadata.displayName = "update" + this.model.name;
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.queriesValidationDto = getUpdateManyQueryValidator(this.modelMetadata);
86
+ endpointMetadata.queryDto = getUpdateManyQueryValidator(this.modelMetadata);
96
87
  //-- body dto ------------------------------------
97
- endpointMetadata.bodyValidationDto = getUpdateManyBodyValidator(this.modelMetadata);
88
+ endpointMetadata.bodyDto = getUpdateManyBodyValidator(this.modelMetadata);
98
89
  //-- response dto ------------------------------------
99
- endpointMetadata.responseValidationDto = getUpdateManyResponseValidator(this.modelMetadata);
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.httpMethod = HttpMethod.PUT;
116
- endpointMetadata.url = `${this.getMountedUrl()}/records`;
117
- endpointMetadata.name = CrudHttpController.prototype.updateRecords.name;
118
- endpointMetadata.displayName = "updateRecords" + this.model.name;
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.queriesValidationDto = getUpdateRecordsQueryValidator();
101
+ endpointMetadata.queryDto = getUpdateRecordsQueryValidator();
121
102
  //-- body dto ------------------------------------
122
- endpointMetadata.bodyValidationDto = getUpdateRecordsBodyValidator(this.modelMetadata);
103
+ endpointMetadata.bodyDto = getUpdateRecordsBodyValidator(this.modelMetadata);
123
104
  //-- response dto ------------------------------------
124
- endpointMetadata.responseValidationDto = getUpdateManyResponseValidator(this.modelMetadata);
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.httpMethod = HttpMethod.DEL;
142
- endpointMetadata.url = this.getMountedUrl();
143
- endpointMetadata.name = CrudHttpController.prototype.deleteMany.name;
144
- endpointMetadata.displayName = "delete" + this.model.name;
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.queriesValidationDto = getUpdateManyQueryValidator(this.modelMetadata);
147
- endpointMetadata.responseValidationDto = getUpdateManyResponseValidator(this.modelMetadata);
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.httpMethod === endpoint.httpMethod && e.url === endpoint.url) ||
188
- (e.name === endpoint.name && (!e.httpMethod || !e.url)));
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", [HttpRequest]),
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", [HttpRequest]),
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", [HttpRequest]),
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", [HttpRequest]),
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", [HttpRequest]),
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: MountedEndpointInfo, req: HttpRequest): Promise<HttpResponse<any>>;
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.endpointMetadata.params || {}).map((p) => {
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.endpoint.controller[endpoint.endpointMetadata.name](...params);
48
+ const response = await endpoint.controller[endpoint.handlerFunctionName](...params);
49
49
  //-- validate response value against response dto
50
- if (endpoint.endpointMetadata.responseValidationDto) {
51
- response.value = stripData(response.value, endpoint.endpointMetadata.responseValidationDto);
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.endpointMetadata.httpMethod === method &&
65
- match(info.endpointMetadata.url, { decode: decodeURIComponent })(result.pathname || "/");
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.endpointMetadata);
86
+ }, info);
87
87
  const authInfo = await this.principalResolver.resolvePrincipal(request);
88
88
  request.setAuthInfo(authInfo);
89
- if (!info.endpointMetadata.openAccess) {
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.endpointMetadata);
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 { HttpMethod, Constructor, AbstractModel } from "@clairejs/core";
2
- import { AbstractHttpController } from "./controller/AbstractHttpController";
3
- import { AbstractAccessCondition } from "./security/AbstractAccessCondition";
4
- import { HttpResponse } from "./common/HttpResponse";
5
- import { UriMapperHandler } from "./file-upload/types";
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;
@@ -1,13 +1,13 @@
1
- import { initFieldMetadata, getObjectMetadata, HttpMethod, DataType, } from "@clairejs/core";
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.httpMethod = config.method;
8
+ endpointMetadata.method = config.method;
9
9
  //-- default to "/" if empty string is provided
10
- endpointMetadata.url = config.url || "/";
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.responseValidationDto = { id: "", primitiveType: DataType.STRING, fields: [] };
21
+ endpointMetadata.responseDto = { id: "", primitiveType: DataType.STRING, fields: [] };
22
22
  }
23
23
  else if (responseClass === Number) {
24
- endpointMetadata.responseValidationDto = { id: "", primitiveType: DataType.NUMBER, fields: [] };
24
+ endpointMetadata.responseDto = { id: "", primitiveType: DataType.NUMBER, fields: [] };
25
25
  }
26
26
  else if (responseClass === Boolean) {
27
- endpointMetadata.responseValidationDto = { id: "", primitiveType: DataType.BOOLEAN, fields: [] };
27
+ endpointMetadata.responseDto = { id: "", primitiveType: DataType.BOOLEAN, fields: [] };
28
28
  }
29
29
  else {
30
- endpointMetadata.responseValidationDto = getObjectMetadata(responseClass);
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.bodyValidationDto = getObjectMetadata(paramClasses[paramIndex]);
38
+ endpointMetadata.bodyDto = getObjectMetadata(paramClasses[paramIndex]);
51
39
  break;
52
40
  case "params":
53
- endpointMetadata.paramsValidationDto = getObjectMetadata(paramClasses[paramIndex]);
41
+ endpointMetadata.paramDto = getObjectMetadata(paramClasses[paramIndex]);
54
42
  break;
55
43
  case "queries":
56
- endpointMetadata.queriesValidationDto = getObjectMetadata(paramClasses[paramIndex]);
44
+ endpointMetadata.queryDto = getObjectMetadata(paramClasses[paramIndex]);
57
45
  break;
58
46
  default:
59
47
  break;