@ruiapp/rapid-core 0.2.14 → 0.3.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 (32) hide show
  1. package/dist/core/routeContext.d.ts +2 -2
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.js +231 -19
  4. package/dist/plugins/mail/MailPlugin.d.ts +23 -0
  5. package/dist/plugins/mail/MailPluginTypes.d.ts +24 -0
  6. package/dist/plugins/mail/MailService.d.ts +8 -0
  7. package/dist/plugins/mail/actionHandlers/index.d.ts +2 -0
  8. package/dist/plugins/mail/models/index.d.ts +2 -0
  9. package/dist/plugins/mail/routes/index.d.ts +2 -0
  10. package/dist/plugins/notification/NotificationPlugin.d.ts +21 -0
  11. package/dist/plugins/notification/NotificationPluginTypes.d.ts +12 -0
  12. package/dist/plugins/notification/NotificationService.d.ts +8 -0
  13. package/dist/plugins/notification/actionHandlers/index.d.ts +2 -0
  14. package/dist/plugins/notification/models/Notification.d.ts +3 -0
  15. package/dist/plugins/notification/models/index.d.ts +2 -0
  16. package/dist/plugins/notification/routes/index.d.ts +2 -0
  17. package/package.json +3 -1
  18. package/src/core/routeContext.ts +9 -5
  19. package/src/index.ts +6 -0
  20. package/src/plugins/mail/MailPlugin.ts +74 -0
  21. package/src/plugins/mail/MailPluginTypes.ts +27 -0
  22. package/src/plugins/mail/MailService.ts +38 -0
  23. package/src/plugins/mail/actionHandlers/index.ts +3 -0
  24. package/src/plugins/mail/models/index.ts +1 -0
  25. package/src/plugins/mail/routes/index.ts +1 -0
  26. package/src/plugins/notification/NotificationPlugin.ts +68 -0
  27. package/src/plugins/notification/NotificationPluginTypes.ts +13 -0
  28. package/src/plugins/notification/NotificationService.ts +25 -0
  29. package/src/plugins/notification/actionHandlers/index.ts +3 -0
  30. package/src/plugins/notification/models/Notification.ts +60 -0
  31. package/src/plugins/notification/models/index.ts +3 -0
  32. package/src/plugins/notification/routes/index.ts +1 -0
@@ -4,7 +4,6 @@ import { HttpStatus } from "./http-types";
4
4
  import { IRpdServer } from "./server";
5
5
  export type Next = () => Promise<void>;
6
6
  export declare class RouteContext {
7
- #private;
8
7
  readonly request: RapidRequest;
9
8
  readonly response: RapidResponse;
10
9
  readonly state: Record<string, any>;
@@ -12,7 +11,8 @@ export declare class RouteContext {
12
11
  path: string;
13
12
  params: Record<string, string>;
14
13
  routeConfig: any;
15
- constructor(server: IRpdServer, request: RapidRequest);
14
+ static newSystemOperationContext(server: IRpdServer): RouteContext;
15
+ constructor(server: IRpdServer, request?: RapidRequest);
16
16
  set(headerName: string, headerValue: string): void;
17
17
  json(obj: any, status?: HttpStatus, headers?: HeadersInit): void;
18
18
  redirect(url: string, status?: HttpStatus): void;
package/dist/index.d.ts CHANGED
@@ -16,6 +16,10 @@ export * from "./plugins/sequence/SequencePluginTypes";
16
16
  export { default as WebhooksPlugin } from "./plugins/webhooks/WebhooksPlugin";
17
17
  export { default as AuthPlugin } from "./plugins/auth/AuthPlugin";
18
18
  export { default as FileManagePlugin } from "./plugins/fileManage/FileManagePlugin";
19
+ export { default as MailPlugin } from "./plugins/mail/MailPlugin";
20
+ export * from "./plugins/mail/MailPluginTypes";
21
+ export { default as NotificationPlugin } from "./plugins/notification/NotificationPlugin";
22
+ export * from "./plugins/notification/NotificationPluginTypes";
19
23
  export { default as ServerOperationPlugin } from "./plugins/serverOperation/ServerOperationPlugin";
20
24
  export * from "./plugins/serverOperation/ServerOperationPluginTypes";
21
25
  export { default as SettingPlugin } from "./plugins/setting/SettingPlugin";
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ var bcrypt = require('bcrypt');
13
13
  var path = require('path');
14
14
  var fs = require('fs');
15
15
  var uuid = require('uuid');
16
+ var nodemailer = require('nodemailer');
16
17
  var cron = require('cron');
17
18
  var xstate = require('xstate');
18
19
 
@@ -43,6 +44,7 @@ var crypto__default = /*#__PURE__*/_interopDefaultLegacy(crypto);
43
44
  var bcrypt__default = /*#__PURE__*/_interopDefaultLegacy(bcrypt);
44
45
  var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
45
46
  var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs);
47
+ var nodemailer__default = /*#__PURE__*/_interopDefaultLegacy(nodemailer);
46
48
  var cron__namespace = /*#__PURE__*/_interopNamespace(cron);
47
49
 
48
50
  function fixBigIntJSONSerialize() {
@@ -1040,7 +1042,6 @@ class RapidResponse {
1040
1042
  }
1041
1043
 
1042
1044
  class RouteContext {
1043
- #logger;
1044
1045
  request;
1045
1046
  response;
1046
1047
  state;
@@ -1048,14 +1049,18 @@ class RouteContext {
1048
1049
  path;
1049
1050
  params;
1050
1051
  routeConfig;
1052
+ static newSystemOperationContext(server) {
1053
+ return new RouteContext(server);
1054
+ }
1051
1055
  constructor(server, request) {
1052
- this.#logger = server.getLogger();
1053
1056
  this.request = request;
1054
1057
  this.state = {};
1055
1058
  this.response = new RapidResponse();
1056
1059
  // `method` and `path` are used by `koa-tree-router` to match route
1057
- this.method = request.method;
1058
- this.path = request.url.pathname;
1060
+ if (this.request) {
1061
+ this.method = request.method;
1062
+ this.path = request.url.pathname;
1063
+ }
1059
1064
  }
1060
1065
  // `koa-tree-router` uses this method to set headers
1061
1066
  set(headerName, headerValue) {
@@ -5367,7 +5372,7 @@ var generateSn$1 = /*#__PURE__*/Object.freeze({
5367
5372
  handler: handler$e
5368
5373
  });
5369
5374
 
5370
- var pluginActionHandlers$5 = [generateSn$1];
5375
+ var pluginActionHandlers$7 = [generateSn$1];
5371
5376
 
5372
5377
  var SequenceRule = {
5373
5378
  maintainedBy: "sequencePlugin",
@@ -5458,7 +5463,7 @@ var SequenceAutoIncrementRecord = {
5458
5463
  ],
5459
5464
  };
5460
5465
 
5461
- var pluginModels$3 = [SequenceRule, SequenceAutoIncrementRecord];
5466
+ var pluginModels$5 = [SequenceRule, SequenceAutoIncrementRecord];
5462
5467
 
5463
5468
  var generateSn = {
5464
5469
  namespace: "svc",
@@ -5474,7 +5479,7 @@ var generateSn = {
5474
5479
  ],
5475
5480
  };
5476
5481
 
5477
- var pluginRoutes$5 = [generateSn];
5482
+ var pluginRoutes$7 = [generateSn];
5478
5483
 
5479
5484
  const segmentType$5 = "literal";
5480
5485
  async function resolveSegmentValue$5(server, ruleCode, config, input) {
@@ -5670,7 +5675,7 @@ class SequenceService {
5670
5675
  /**
5671
5676
  * Sequence plugin
5672
5677
  */
5673
- class SequencePlugin {
5678
+ class SequencePlugin$1 {
5674
5679
  #sequenceService;
5675
5680
  get sequenceService() {
5676
5681
  return this.#sequenceService;
@@ -5691,19 +5696,19 @@ class SequencePlugin {
5691
5696
  return [];
5692
5697
  }
5693
5698
  async registerActionHandlers(server) {
5694
- for (const actionHandler of pluginActionHandlers$5) {
5699
+ for (const actionHandler of pluginActionHandlers$7) {
5695
5700
  server.registerActionHandler(this, actionHandler);
5696
5701
  }
5697
5702
  }
5698
5703
  async configureModels(server, applicationConfig) {
5699
- server.appendApplicationConfig({ models: pluginModels$3 });
5704
+ server.appendApplicationConfig({ models: pluginModels$5 });
5700
5705
  }
5701
5706
  async configureServices(server, applicationConfig) {
5702
5707
  this.#sequenceService = new SequenceService(server);
5703
5708
  server.registerService("sequenceService", this.#sequenceService);
5704
5709
  }
5705
5710
  async configureRoutes(server, applicationConfig) {
5706
- server.appendApplicationConfig({ routes: pluginRoutes$5 });
5711
+ server.appendApplicationConfig({ routes: pluginRoutes$7 });
5707
5712
  }
5708
5713
  async onApplicationLoaded(server, applicationConfig) {
5709
5714
  const models = server.getApplicationConfig().models;
@@ -6124,7 +6129,7 @@ var resetPassword$1 = /*#__PURE__*/Object.freeze({
6124
6129
  handler: handler$9
6125
6130
  });
6126
6131
 
6127
- var pluginActionHandlers$4 = [changePassword$1, createSession, deleteSession, getMyProfile$2, resetPassword$1];
6132
+ var pluginActionHandlers$6 = [changePassword$1, createSession, deleteSession, getMyProfile$2, resetPassword$1];
6128
6133
 
6129
6134
  var AccessToken = {
6130
6135
  maintainedBy: "authManager",
@@ -6181,7 +6186,7 @@ var AccessToken = {
6181
6186
  ],
6182
6187
  };
6183
6188
 
6184
- var pluginModels$2 = [AccessToken];
6189
+ var pluginModels$4 = [AccessToken];
6185
6190
 
6186
6191
  var changePassword = {
6187
6192
  namespace: "auth",
@@ -6253,7 +6258,7 @@ var signout$1 = {
6253
6258
  ],
6254
6259
  };
6255
6260
 
6256
- var pluginRoutes$4 = [changePassword, getMyProfile$1, resetPassword, signin$1, signout$1];
6261
+ var pluginRoutes$6 = [changePassword, getMyProfile$1, resetPassword, signin$1, signout$1];
6257
6262
 
6258
6263
  /**
6259
6264
  * Auth manager plugin
@@ -6275,15 +6280,15 @@ class AuthPlugin {
6275
6280
  return [];
6276
6281
  }
6277
6282
  async registerActionHandlers(server) {
6278
- for (const actionHandler of pluginActionHandlers$4) {
6283
+ for (const actionHandler of pluginActionHandlers$6) {
6279
6284
  server.registerActionHandler(this, actionHandler);
6280
6285
  }
6281
6286
  }
6282
6287
  async configureModels(server, applicationConfig) {
6283
- server.appendApplicationConfig({ models: pluginModels$2 });
6288
+ server.appendApplicationConfig({ models: pluginModels$4 });
6284
6289
  }
6285
6290
  async configureRoutes(server, applicationConfig) {
6286
- server.appendApplicationConfig({ routes: pluginRoutes$4 });
6291
+ server.appendApplicationConfig({ routes: pluginRoutes$6 });
6287
6292
  }
6288
6293
  async onPrepareRouteContext(server, routeContext) {
6289
6294
  const request = routeContext.request;
@@ -6504,7 +6509,7 @@ var signout = {
6504
6509
  ],
6505
6510
  };
6506
6511
 
6507
- var pluginRoutes$3 = [getMyProfile, signin, signout];
6512
+ var pluginRoutes$5 = [getMyProfile, signin, signout];
6508
6513
 
6509
6514
  /**
6510
6515
  * File manager plugin
@@ -6530,9 +6535,214 @@ class FileManager {
6530
6535
  server.registerActionHandler(this, downloadFileActionHandler);
6531
6536
  server.registerActionHandler(this, uploadFileActionHandler);
6532
6537
  }
6538
+ async configureRoutes(server, applicationConfig) {
6539
+ server.appendApplicationConfig({ routes: pluginRoutes$5 });
6540
+ }
6541
+ }
6542
+
6543
+ var pluginActionHandlers$5 = [];
6544
+
6545
+ var pluginModels$3 = [];
6546
+
6547
+ var pluginRoutes$4 = [];
6548
+
6549
+ class MailService {
6550
+ #server;
6551
+ #smtpServer;
6552
+ constructor(server, smtpServer) {
6553
+ this.#server = server;
6554
+ this.#smtpServer = smtpServer;
6555
+ }
6556
+ async sendMail(routeContext, server, options) {
6557
+ const smtpServer = this.#smtpServer;
6558
+ const transporter = nodemailer__default["default"].createTransport({
6559
+ host: smtpServer.host,
6560
+ port: smtpServer.port,
6561
+ secure: smtpServer.secure,
6562
+ auth: {
6563
+ user: smtpServer.username,
6564
+ pass: smtpServer.password,
6565
+ },
6566
+ });
6567
+ const info = await transporter.sendMail({
6568
+ from: options.from,
6569
+ to: options.to,
6570
+ subject: options.subject,
6571
+ text: options.text,
6572
+ html: options.html,
6573
+ });
6574
+ return info;
6575
+ }
6576
+ }
6577
+
6578
+ /**
6579
+ * Mail plugin
6580
+ */
6581
+ class MailPlugin {
6582
+ #mailService;
6583
+ #config;
6584
+ constructor(config) {
6585
+ this.#config = config;
6586
+ }
6587
+ get mailService() {
6588
+ return this.#mailService;
6589
+ }
6590
+ get code() {
6591
+ return "mail";
6592
+ }
6593
+ get description() {
6594
+ return null;
6595
+ }
6596
+ get extendingAbilities() {
6597
+ return [];
6598
+ }
6599
+ get configurableTargets() {
6600
+ return [];
6601
+ }
6602
+ get configurations() {
6603
+ return [];
6604
+ }
6605
+ async registerActionHandlers(server) {
6606
+ for (const actionHandler of pluginActionHandlers$5) {
6607
+ server.registerActionHandler(this, actionHandler);
6608
+ }
6609
+ }
6610
+ async configureModels(server, applicationConfig) {
6611
+ server.appendApplicationConfig({ models: pluginModels$3 });
6612
+ }
6613
+ async configureServices(server, applicationConfig) {
6614
+ this.#mailService = new MailService(server, this.#config.smtpServer);
6615
+ server.registerService("mailService", this.#mailService);
6616
+ }
6617
+ async configureRoutes(server, applicationConfig) {
6618
+ server.appendApplicationConfig({ routes: pluginRoutes$4 });
6619
+ }
6620
+ async onApplicationLoaded(server, applicationConfig) { }
6621
+ }
6622
+
6623
+ var pluginActionHandlers$4 = [];
6624
+
6625
+ var Notification = {
6626
+ maintainedBy: "notification",
6627
+ namespace: "svc",
6628
+ name: "notification",
6629
+ singularCode: "notification",
6630
+ pluralCode: "notifications",
6631
+ schema: "public",
6632
+ tableName: "notifications",
6633
+ properties: [
6634
+ {
6635
+ name: "id",
6636
+ code: "id",
6637
+ columnName: "id",
6638
+ type: "integer",
6639
+ required: true,
6640
+ autoIncrement: true,
6641
+ },
6642
+ {
6643
+ name: "标题",
6644
+ code: "title",
6645
+ columnName: "title",
6646
+ type: "text",
6647
+ required: true,
6648
+ },
6649
+ {
6650
+ name: "内容",
6651
+ code: "content",
6652
+ columnName: "content",
6653
+ type: "text",
6654
+ required: false,
6655
+ },
6656
+ {
6657
+ name: "已读",
6658
+ code: "read",
6659
+ columnName: "read",
6660
+ type: "boolean",
6661
+ required: false,
6662
+ defaultValue: "false",
6663
+ },
6664
+ {
6665
+ name: "详细信息",
6666
+ code: "details",
6667
+ columnName: "details",
6668
+ description: '{"url": "", "actions": [{"text": "", "url": ""}]}',
6669
+ type: "json",
6670
+ required: false,
6671
+ },
6672
+ {
6673
+ name: "用户",
6674
+ code: "user",
6675
+ type: "relation",
6676
+ required: false,
6677
+ relation: "one",
6678
+ targetSingularCode: "oc_user",
6679
+ targetIdColumnName: "user_id",
6680
+ },
6681
+ ],
6682
+ };
6683
+
6684
+ var pluginModels$2 = [Notification];
6685
+
6686
+ var pluginRoutes$3 = [];
6687
+
6688
+ class NotificationService {
6689
+ #server;
6690
+ constructor(server) {
6691
+ this.#server = server;
6692
+ }
6693
+ async sendNotification(routeContext, server, options) {
6694
+ const notificationManager = server.getEntityManager("notification");
6695
+ return await notificationManager.createEntity({
6696
+ routeContext,
6697
+ entity: {
6698
+ title: options.title,
6699
+ content: options.content,
6700
+ details: options.details,
6701
+ user: options.userId,
6702
+ },
6703
+ });
6704
+ }
6705
+ }
6706
+
6707
+ /**
6708
+ * Notification plugin
6709
+ */
6710
+ class SequencePlugin {
6711
+ #notificationService;
6712
+ get notificationService() {
6713
+ return this.#notificationService;
6714
+ }
6715
+ get code() {
6716
+ return "notification";
6717
+ }
6718
+ get description() {
6719
+ return null;
6720
+ }
6721
+ get extendingAbilities() {
6722
+ return [];
6723
+ }
6724
+ get configurableTargets() {
6725
+ return [];
6726
+ }
6727
+ get configurations() {
6728
+ return [];
6729
+ }
6730
+ async registerActionHandlers(server) {
6731
+ for (const actionHandler of pluginActionHandlers$4) {
6732
+ server.registerActionHandler(this, actionHandler);
6733
+ }
6734
+ }
6735
+ async configureModels(server, applicationConfig) {
6736
+ server.appendApplicationConfig({ models: pluginModels$2 });
6737
+ }
6738
+ async configureServices(server, applicationConfig) {
6739
+ this.#notificationService = new NotificationService(server);
6740
+ server.registerService("notificationService", this.#notificationService);
6741
+ }
6533
6742
  async configureRoutes(server, applicationConfig) {
6534
6743
  server.appendApplicationConfig({ routes: pluginRoutes$3 });
6535
6744
  }
6745
+ async onApplicationLoaded(server, applicationConfig) { }
6536
6746
  }
6537
6747
 
6538
6748
  const code$5 = "runServerOperation";
@@ -7831,12 +8041,14 @@ exports.DataManagePlugin = DataManager;
7831
8041
  exports.EntityAccessControlPlugin = EntityAccessControlPlugin;
7832
8042
  exports.FileManagePlugin = FileManager;
7833
8043
  exports.GlobalRequest = GlobalRequest;
8044
+ exports.MailPlugin = MailPlugin;
7834
8045
  exports.MetaManagePlugin = MetaManager;
8046
+ exports.NotificationPlugin = SequencePlugin;
7835
8047
  exports.RapidRequest = RapidRequest;
7836
8048
  exports.RapidServer = RapidServer;
7837
8049
  exports.RouteContext = RouteContext;
7838
8050
  exports.RouteManagePlugin = RouteManager;
7839
- exports.SequencePlugin = SequencePlugin;
8051
+ exports.SequencePlugin = SequencePlugin$1;
7840
8052
  exports.ServerOperationPlugin = ServerOperationPlugin;
7841
8053
  exports.SettingPlugin = SettingPlugin;
7842
8054
  exports.StateMachinePlugin = StateMachinePlugin;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Mail plugin
3
+ */
4
+ import { RpdApplicationConfig } from "../../types";
5
+ import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
6
+ import MailService from "./MailService";
7
+ import { MailPluginConfig } from "./MailPluginTypes";
8
+ declare class MailPlugin implements RapidPlugin {
9
+ #private;
10
+ constructor(config: MailPluginConfig);
11
+ get mailService(): MailService;
12
+ get code(): string;
13
+ get description(): string;
14
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[];
15
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[];
16
+ get configurations(): RpdConfigurationItemOptions[];
17
+ registerActionHandlers(server: IRpdServer): Promise<any>;
18
+ configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
19
+ configureServices(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
20
+ configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
21
+ onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<void>;
22
+ }
23
+ export default MailPlugin;
@@ -0,0 +1,24 @@
1
+ export type MailPluginConfig = {
2
+ smtpServer: RpdMailSmtpServer;
3
+ };
4
+ export type RpdMailSmtpServer = {
5
+ host: string;
6
+ port: number;
7
+ secure: boolean;
8
+ username: string;
9
+ password: string;
10
+ };
11
+ export type RpdMail = {
12
+ from?: string;
13
+ to?: string;
14
+ subject?: string;
15
+ text?: string;
16
+ html?: string;
17
+ };
18
+ export type SendMailOptions = {
19
+ from?: string;
20
+ to?: string;
21
+ subject?: string;
22
+ text?: string;
23
+ html?: string;
24
+ };
@@ -0,0 +1,8 @@
1
+ import { IRpdServer } from "../../core/server";
2
+ import { RpdMailSmtpServer, SendMailOptions } from "./MailPluginTypes";
3
+ import { RouteContext } from "../../core/routeContext";
4
+ export default class MailService {
5
+ #private;
6
+ constructor(server: IRpdServer, smtpServer: RpdMailSmtpServer);
7
+ sendMail(routeContext: RouteContext, server: IRpdServer, options: SendMailOptions): Promise<any>;
8
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: any[];
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: any[];
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: any[];
2
+ export default _default;
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Notification plugin
3
+ */
4
+ import { RpdApplicationConfig } from "../../types";
5
+ import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
6
+ import NotificationService from "./NotificationService";
7
+ declare class SequencePlugin implements RapidPlugin {
8
+ #private;
9
+ get notificationService(): NotificationService;
10
+ get code(): string;
11
+ get description(): string;
12
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[];
13
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[];
14
+ get configurations(): RpdConfigurationItemOptions[];
15
+ registerActionHandlers(server: IRpdServer): Promise<any>;
16
+ configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
17
+ configureServices(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
18
+ configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
19
+ onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<void>;
20
+ }
21
+ export default SequencePlugin;
@@ -0,0 +1,12 @@
1
+ export type RpdNotification = {
2
+ id?: number;
3
+ title: string;
4
+ content?: string;
5
+ details?: any;
6
+ };
7
+ export type SendNotificationOptions = {
8
+ userId: number;
9
+ title: string;
10
+ content?: string;
11
+ details?: any;
12
+ };
@@ -0,0 +1,8 @@
1
+ import { IRpdServer } from "../../core/server";
2
+ import { SendNotificationOptions, RpdNotification } from "./NotificationPluginTypes";
3
+ import { RouteContext } from "../../core/routeContext";
4
+ export default class NotificationService {
5
+ #private;
6
+ constructor(server: IRpdServer);
7
+ sendNotification(routeContext: RouteContext, server: IRpdServer, options: SendNotificationOptions): Promise<RpdNotification>;
8
+ }
@@ -0,0 +1,2 @@
1
+ declare const _default: any[];
2
+ export default _default;
@@ -0,0 +1,3 @@
1
+ import { RpdDataModel } from "../../../types";
2
+ declare const _default: RpdDataModel;
3
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: import("../../..").RpdDataModel[];
2
+ export default _default;
@@ -0,0 +1,2 @@
1
+ declare const _default: any[];
2
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ruiapp/rapid-core",
3
- "version": "0.2.14",
3
+ "version": "0.3.1",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,6 +11,7 @@
11
11
  "@types/jsonwebtoken": "^9.0.5",
12
12
  "@types/lodash": "^4.14.186",
13
13
  "@types/node": "^20.11.16",
14
+ "@types/nodemailer": "^6.4.16",
14
15
  "rimraf": "^3.0.2",
15
16
  "rollup": "^2.79.1",
16
17
  "rollup-plugin-tsc-alias": "^1.1.2",
@@ -29,6 +30,7 @@
29
30
  "xstate": "^5.13.0"
30
31
  },
31
32
  "peerDependencies": {
33
+ "nodemailer": "^6.9.15",
32
34
  "winston": "^3.11.0"
33
35
  },
34
36
  "scripts": {
@@ -8,7 +8,6 @@ import { Logger } from "~/facilities/log/LogFacility";
8
8
  export type Next = () => Promise<void>;
9
9
 
10
10
  export class RouteContext {
11
- #logger: Logger;
12
11
  readonly request: RapidRequest;
13
12
  readonly response: RapidResponse;
14
13
  readonly state: Record<string, any>;
@@ -17,15 +16,20 @@ export class RouteContext {
17
16
  params: Record<string, string>;
18
17
  routeConfig: any;
19
18
 
20
- constructor(server: IRpdServer, request: RapidRequest) {
21
- this.#logger = server.getLogger();
19
+ static newSystemOperationContext(server: IRpdServer) {
20
+ return new RouteContext(server);
21
+ }
22
+
23
+ constructor(server: IRpdServer, request?: RapidRequest) {
22
24
  this.request = request;
23
25
  this.state = {};
24
26
  this.response = new RapidResponse();
25
27
 
26
28
  // `method` and `path` are used by `koa-tree-router` to match route
27
- this.method = request.method;
28
- this.path = request.url.pathname;
29
+ if (this.request) {
30
+ this.method = request.method;
31
+ this.path = request.url.pathname;
32
+ }
29
33
  }
30
34
 
31
35
  // `koa-tree-router` uses this method to set headers
package/src/index.ts CHANGED
@@ -31,6 +31,12 @@ export { default as AuthPlugin } from "./plugins/auth/AuthPlugin";
31
31
 
32
32
  export { default as FileManagePlugin } from "./plugins/fileManage/FileManagePlugin";
33
33
 
34
+ export { default as MailPlugin } from "./plugins/mail/MailPlugin";
35
+ export * from "./plugins/mail/MailPluginTypes";
36
+
37
+ export { default as NotificationPlugin } from "./plugins/notification/NotificationPlugin";
38
+ export * from "./plugins/notification/NotificationPluginTypes";
39
+
34
40
  export { default as ServerOperationPlugin } from "./plugins/serverOperation/ServerOperationPlugin";
35
41
  export * from "./plugins/serverOperation/ServerOperationPluginTypes";
36
42
 
@@ -0,0 +1,74 @@
1
+ /**
2
+ * Mail plugin
3
+ */
4
+
5
+ import { RpdApplicationConfig } from "~/types";
6
+ import {
7
+ IRpdServer,
8
+ RapidPlugin,
9
+ RpdConfigurationItemOptions,
10
+ RpdServerPluginConfigurableTargetOptions,
11
+ RpdServerPluginExtendingAbilities,
12
+ } from "~/core/server";
13
+
14
+ import pluginActionHandlers from "./actionHandlers";
15
+ import pluginModels from "./models";
16
+ import pluginRoutes from "./routes";
17
+ import MailService from "./MailService";
18
+ import { MailPluginConfig } from "./MailPluginTypes";
19
+
20
+ class MailPlugin implements RapidPlugin {
21
+ #mailService!: MailService;
22
+ #config: MailPluginConfig;
23
+
24
+ constructor(config: MailPluginConfig) {
25
+ this.#config = config;
26
+ }
27
+
28
+ get mailService() {
29
+ return this.#mailService;
30
+ }
31
+
32
+ get code(): string {
33
+ return "mail";
34
+ }
35
+
36
+ get description(): string {
37
+ return null;
38
+ }
39
+
40
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[] {
41
+ return [];
42
+ }
43
+
44
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[] {
45
+ return [];
46
+ }
47
+
48
+ get configurations(): RpdConfigurationItemOptions[] {
49
+ return [];
50
+ }
51
+
52
+ async registerActionHandlers(server: IRpdServer): Promise<any> {
53
+ for (const actionHandler of pluginActionHandlers) {
54
+ server.registerActionHandler(this, actionHandler);
55
+ }
56
+ }
57
+
58
+ async configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
59
+ server.appendApplicationConfig({ models: pluginModels });
60
+ }
61
+
62
+ async configureServices(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
63
+ this.#mailService = new MailService(server, this.#config.smtpServer);
64
+ server.registerService("mailService", this.#mailService);
65
+ }
66
+
67
+ async configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
68
+ server.appendApplicationConfig({ routes: pluginRoutes });
69
+ }
70
+
71
+ async onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig) {}
72
+ }
73
+
74
+ export default MailPlugin;
@@ -0,0 +1,27 @@
1
+ export type MailPluginConfig = {
2
+ smtpServer: RpdMailSmtpServer;
3
+ };
4
+
5
+ export type RpdMailSmtpServer = {
6
+ host: string;
7
+ port: number;
8
+ secure: boolean; // true for port 465, false for other ports (normally 587).
9
+ username: string;
10
+ password: string;
11
+ };
12
+
13
+ export type RpdMail = {
14
+ from?: string;
15
+ to?: string;
16
+ subject?: string;
17
+ text?: string;
18
+ html?: string;
19
+ };
20
+
21
+ export type SendMailOptions = {
22
+ from?: string;
23
+ to?: string;
24
+ subject?: string;
25
+ text?: string;
26
+ html?: string;
27
+ };
@@ -0,0 +1,38 @@
1
+ import { IRpdServer } from "~/core/server";
2
+ import { RpdMailSmtpServer, SendMailOptions } from "./MailPluginTypes";
3
+ import { RouteContext } from "~/core/routeContext";
4
+ import nodemailer from "nodemailer";
5
+
6
+ export default class MailService {
7
+ #server: IRpdServer;
8
+ #smtpServer: RpdMailSmtpServer;
9
+
10
+ constructor(server: IRpdServer, smtpServer: RpdMailSmtpServer) {
11
+ this.#server = server;
12
+ this.#smtpServer = smtpServer;
13
+ }
14
+
15
+ async sendMail(routeContext: RouteContext, server: IRpdServer, options: SendMailOptions): Promise<any> {
16
+ const smtpServer = this.#smtpServer;
17
+
18
+ const transporter = nodemailer.createTransport({
19
+ host: smtpServer.host,
20
+ port: smtpServer.port,
21
+ secure: smtpServer.secure, // true for port 465, false for other ports
22
+ auth: {
23
+ user: smtpServer.username,
24
+ pass: smtpServer.password,
25
+ },
26
+ });
27
+
28
+ const info = await transporter.sendMail({
29
+ from: options.from,
30
+ to: options.to,
31
+ subject: options.subject,
32
+ text: options.text,
33
+ html: options.html,
34
+ });
35
+
36
+ return info;
37
+ }
38
+ }
@@ -0,0 +1,3 @@
1
+ import { IPluginActionHandler } from "~/core/actionHandler";
2
+
3
+ export default [] satisfies IPluginActionHandler[];
@@ -0,0 +1 @@
1
+ export default [];
@@ -0,0 +1 @@
1
+ export default [];
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Notification plugin
3
+ */
4
+
5
+ import { RpdApplicationConfig } from "~/types";
6
+ import {
7
+ IRpdServer,
8
+ RapidPlugin,
9
+ RpdConfigurationItemOptions,
10
+ RpdServerPluginConfigurableTargetOptions,
11
+ RpdServerPluginExtendingAbilities,
12
+ } from "~/core/server";
13
+
14
+ import pluginActionHandlers from "./actionHandlers";
15
+ import pluginModels from "./models";
16
+ import pluginRoutes from "./routes";
17
+ import NotificationService from "./NotificationService";
18
+
19
+ class SequencePlugin implements RapidPlugin {
20
+ #notificationService!: NotificationService;
21
+
22
+ get notificationService() {
23
+ return this.#notificationService;
24
+ }
25
+
26
+ get code(): string {
27
+ return "notification";
28
+ }
29
+
30
+ get description(): string {
31
+ return null;
32
+ }
33
+
34
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[] {
35
+ return [];
36
+ }
37
+
38
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[] {
39
+ return [];
40
+ }
41
+
42
+ get configurations(): RpdConfigurationItemOptions[] {
43
+ return [];
44
+ }
45
+
46
+ async registerActionHandlers(server: IRpdServer): Promise<any> {
47
+ for (const actionHandler of pluginActionHandlers) {
48
+ server.registerActionHandler(this, actionHandler);
49
+ }
50
+ }
51
+
52
+ async configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
53
+ server.appendApplicationConfig({ models: pluginModels });
54
+ }
55
+
56
+ async configureServices(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
57
+ this.#notificationService = new NotificationService(server);
58
+ server.registerService("notificationService", this.#notificationService);
59
+ }
60
+
61
+ async configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
62
+ server.appendApplicationConfig({ routes: pluginRoutes });
63
+ }
64
+
65
+ async onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig) {}
66
+ }
67
+
68
+ export default SequencePlugin;
@@ -0,0 +1,13 @@
1
+ export type RpdNotification = {
2
+ id?: number;
3
+ title: string;
4
+ content?: string;
5
+ details?: any;
6
+ };
7
+
8
+ export type SendNotificationOptions = {
9
+ userId: number;
10
+ title: string;
11
+ content?: string;
12
+ details?: any;
13
+ };
@@ -0,0 +1,25 @@
1
+ import { IRpdServer } from "~/core/server";
2
+ import { SendNotificationOptions, RpdNotification } from "./NotificationPluginTypes";
3
+ import { RouteContext } from "~/core/routeContext";
4
+
5
+ export default class NotificationService {
6
+ #server: IRpdServer;
7
+
8
+ constructor(server: IRpdServer) {
9
+ this.#server = server;
10
+ }
11
+
12
+ async sendNotification(routeContext: RouteContext, server: IRpdServer, options: SendNotificationOptions): Promise<RpdNotification> {
13
+ const notificationManager = server.getEntityManager("notification");
14
+
15
+ return await notificationManager.createEntity({
16
+ routeContext,
17
+ entity: {
18
+ title: options.title,
19
+ content: options.content,
20
+ details: options.details,
21
+ user: options.userId,
22
+ },
23
+ });
24
+ }
25
+ }
@@ -0,0 +1,3 @@
1
+ import { IPluginActionHandler } from "~/core/actionHandler";
2
+
3
+ export default [] satisfies IPluginActionHandler[];
@@ -0,0 +1,60 @@
1
+ import { RpdDataModel } from "~/types";
2
+
3
+ export default {
4
+ maintainedBy: "notification",
5
+ namespace: "svc",
6
+ name: "notification",
7
+ singularCode: "notification",
8
+ pluralCode: "notifications",
9
+ schema: "public",
10
+ tableName: "notifications",
11
+ properties: [
12
+ {
13
+ name: "id",
14
+ code: "id",
15
+ columnName: "id",
16
+ type: "integer",
17
+ required: true,
18
+ autoIncrement: true,
19
+ },
20
+ {
21
+ name: "标题",
22
+ code: "title",
23
+ columnName: "title",
24
+ type: "text",
25
+ required: true,
26
+ },
27
+ {
28
+ name: "内容",
29
+ code: "content",
30
+ columnName: "content",
31
+ type: "text",
32
+ required: false,
33
+ },
34
+ {
35
+ name: "已读",
36
+ code: "read",
37
+ columnName: "read",
38
+ type: "boolean",
39
+ required: false,
40
+ defaultValue: "false",
41
+ },
42
+ {
43
+ name: "详细信息",
44
+ code: "details",
45
+ columnName: "details",
46
+ description: '{"url": "", "actions": [{"text": "", "url": ""}]}',
47
+ type: "json",
48
+ required: false,
49
+ },
50
+ {
51
+ name: "用户",
52
+ code: "user",
53
+ type: "relation",
54
+ required: false,
55
+ relation: "one",
56
+ targetSingularCode: "oc_user",
57
+ targetIdColumnName: "user_id",
58
+ },
59
+ ],
60
+ } as RpdDataModel;
@@ -0,0 +1,3 @@
1
+ import Notification from "./Notification";
2
+
3
+ export default [Notification];
@@ -0,0 +1 @@
1
+ export default [];