@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
@@ -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>;
@@ -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>;
@@ -1,9 +1,7 @@
1
- import { HttpMethod, getServiceProvider } from "@clairejs/core";
1
+ import { getServiceProvider, pickData, ApiInfo, getObjectMetadata } from "@clairejs/core";
2
2
  import { AbstractHttpRequestHandler } from "./controller/AbstractHttpRequestHandler";
3
3
  import { AbstractServerSocketManager } from "../socket/AbstractServerSocketManager";
4
- export const getEndpointId = (endpoint) => {
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
- permissions: [...httpInfo, ...socketInfo].map((endpointInfo) => ({
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/MountedEndpointInfo";
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/MountedEndpointInfo";
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";
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { FileOperation } from "../common/FileOperation";
2
3
  import { GetUploadUrlResponseBody } from "../controllers/dto/upload";
3
4
  export declare abstract class AbstractFileService {
@@ -13,5 +14,6 @@ export declare abstract class AbstractFileService {
13
14
  toURI: string;
14
15
  }[]): Promise<void>;
15
16
  abstract removeObject(uris: string[]): Promise<void>;
17
+ abstract putFile(uri: string, data: Buffer, headers?: Record<string, string>): Promise<void>;
16
18
  getUploadUrlForTempUri(temporaryUri: string): Promise<GetUploadUrlResponseBody>;
17
19
  }
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { FileOperation } from "../../common/FileOperation";
2
3
  import { AbstractFileService } from "../AbstractFileService";
3
4
  export declare class LocalFileService extends AbstractFileService {
@@ -6,6 +7,7 @@ export declare class LocalFileService extends AbstractFileService {
6
7
  getFileSize(objectKeys: string[]): Promise<number[]>;
7
8
  getAccessUrls(uris: (string | undefined)[], _isPublic: boolean): Promise<string[]>;
8
9
  getPresignedUrl(operation: FileOperation, uris: string[]): Promise<string[]>;
10
+ putFile(uri: string, data: Buffer, headers?: Record<string, string>): Promise<void>;
9
11
  moveObject(uris: {
10
12
  fromURI: string;
11
13
  toURI: string;
@@ -23,6 +23,15 @@ export class LocalFileService extends AbstractFileService {
23
23
  }
24
24
  return uris.map((uri) => `${this.fileServerUrl}/?objectKey="/${uri}"`);
25
25
  }
26
+ async putFile(uri, data, headers) {
27
+ const [url] = await this.getPresignedUrl(FileOperation.PUT, [uri]);
28
+ await axios({
29
+ method: 'PUT',
30
+ url,
31
+ data,
32
+ headers,
33
+ });
34
+ }
26
35
  async moveObject(uris) {
27
36
  await Promise.all(uris.map((uri) => axios.post(`${this.fileServerUrl}/`, {
28
37
  from: uri.fromURI,
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  import { AbstractLogger } from "@clairejs/core";
2
3
  import { FileOperation } from "../../common/FileOperation";
3
4
  import { AbstractFileService } from "../AbstractFileService";
@@ -13,8 +14,9 @@ export declare class S3FileService extends AbstractFileService {
13
14
  protected readonly config: S3FileServiceConfig;
14
15
  protected readonly logger: AbstractLogger;
15
16
  private readonly s3Client;
16
- private readonly cloudfrontSigner;
17
+ private readonly cloudfrontSigner?;
17
18
  constructor(config: S3FileServiceConfig, logger: AbstractLogger);
19
+ putFile(uri: string, data: Buffer, headers?: Record<string, string>): Promise<void>;
18
20
  getFileSize(objectKeys: string[]): Promise<number[]>;
19
21
  getAccessUrls(uris: (string | undefined)[], isPublic: boolean): Promise<string[]>;
20
22
  getPresignedUrl(operation: FileOperation, uris: string[]): Promise<string[]>;
@@ -24,7 +24,17 @@ let S3FileService = class S3FileService extends AbstractFileService {
24
24
  signatureVersion: "v4",
25
25
  region: this.config.S3_BUCKET_REGION,
26
26
  });
27
- this.cloudfrontSigner = new aws.CloudFront.Signer(this.config.CLOUD_FRONT_PUBLIC_KEY_ID, this.config.CLOUD_FRONT_PRIVATE_KEY);
27
+ if (this.config.CLOUD_FRONT_PUBLIC_DOMAIN && this.config.CLOUD_FRONT_PRIVATE_KEY && this.config.CLOUD_FRONT_PUBLIC_KEY_ID) {
28
+ this.cloudfrontSigner = new aws.CloudFront.Signer(this.config.CLOUD_FRONT_PUBLIC_KEY_ID, this.config.CLOUD_FRONT_PRIVATE_KEY);
29
+ }
30
+ }
31
+ async putFile(uri, data, headers) {
32
+ await this.s3Client.putObject({
33
+ Key: uri,
34
+ Bucket: this.config.S3_BUCKET_NAME,
35
+ Body: data,
36
+ Metadata: headers,
37
+ }).promise();
28
38
  }
29
39
  async getFileSize(objectKeys) {
30
40
  return await Promise.all(objectKeys.map((uri) => this.getSingleFileSize(uri)));
@@ -51,10 +61,17 @@ let S3FileService = class S3FileService extends AbstractFileService {
51
61
  .then((res) => res.ContentLength);
52
62
  return size || 0;
53
63
  }
54
- getSinglePresignedUrl(_operation, objectKey) {
55
- return this.cloudfrontSigner.getSignedUrl({
56
- url: `${this.config.CLOUD_FRONT_PUBLIC_DOMAIN}/${objectKey}`,
57
- expires: Date.now() + this.config.PRESIGNED_URL_EXPIRATION_S * 1000,
64
+ getSinglePresignedUrl(operation, objectKey) {
65
+ if (this.cloudfrontSigner) {
66
+ return this.cloudfrontSigner.getSignedUrl({
67
+ url: `${this.config.CLOUD_FRONT_PUBLIC_DOMAIN}/${objectKey}`,
68
+ expires: Date.now() + this.config.PRESIGNED_URL_EXPIRATION_S * 1000,
69
+ });
70
+ }
71
+ return this.s3Client.getSignedUrl(operation, {
72
+ Bucket: this.config.S3_BUCKET_NAME,
73
+ Key: objectKey,
74
+ Expires: this.config.PRESIGNED_URL_EXPIRATION_S
58
75
  });
59
76
  }
60
77
  async copySingleObject(fromObjectKey, toObjectKey) {
@@ -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<MountedEndpointInfo[]>;
45
+ getMountedEndpointInfo(): Promise<EndpointMetadata[]>;
46
46
  }
@@ -1,53 +1,10 @@
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, 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.endpointMetadata.url === channelInfo.name);
117
+ const currentEndpoint = mountedEndpoints.find((e) => e.mount === channelInfo.name);
161
118
  if (currentEndpoint) {
162
- currentEndpoint.endpoint.controller.onChannelLeave(socket);
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.endpointMetadata.url === channel);
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.endpointMetadata);
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.endpointMetadata);
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.endpoint.controller.onChannelJoin(clientSocket)),
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.endpointMetadata.url === channel);
229
+ const currentEndpoint = mountedEndpoints.find((e) => e.mount === channel);
273
230
  if (!currentEndpoint) {
274
231
  return;
275
232
  }
276
- return currentEndpoint.endpoint.controller.onChannelLeave(clientSocket);
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.endpointMetadata.url === channel);
251
+ const currentEndpoint = mountedEndpoints.find((e) => e.mount === channel);
295
252
  if (currentEndpoint) {
296
- const result = await currentEndpoint.endpoint.controller.onMessage(clientSocket, data);
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
- endpoint: {
331
- httpMethod: SocketMethod.MESSAGE,
332
- mount: controller.getChannelName(),
333
- controller: controller,
334
- handlerFunctionName: controller.onMessage.name,
335
- },
336
- endpointMetadata: {
337
- httpMethod: SocketMethod.MESSAGE,
338
- description: "Send / Receive message to / from channel",
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: ${getEndpointId(endpoint.endpoint)}`);
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 { MountedEndpointInfo } from "../common/request/MountedEndpointInfo";
2
+ import { EndpointMetadata } from "../common/request/endpoint-metadata";
3
3
  export interface ServerGlobalStore extends CoreGlobalStore {
4
- mountedEndpointInfo?: MountedEndpointInfo[];
4
+ mountedEndpointInfo?: EndpointMetadata[];
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clairejs/server",
3
- "version": "3.16.19",
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.6.1",
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,7 +0,0 @@
1
- import { HttpMethod, SocketMethod } from "@clairejs/core";
2
- export interface HttpEndpoint {
3
- mount?: string;
4
- httpMethod?: HttpMethod | SocketMethod;
5
- controller: any;
6
- handlerFunctionName: string;
7
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,6 +0,0 @@
1
- import { EndpointMetadata } from "./EndpointMetadata";
2
- import { HttpEndpoint } from "./HttpEndpoint";
3
- export interface MountedEndpointInfo {
4
- endpointMetadata: EndpointMetadata;
5
- endpoint: HttpEndpoint;
6
- }
@@ -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,2 +0,0 @@
1
- export class AbstractAccessCondition {
2
- }
@@ -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
- }