@nocobase/plugin-notifications 0.10.0-alpha.5 → 0.11.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/client.d.ts +3 -0
- package/client.js +1 -0
- package/lib/client/index.d.ts +5 -0
- package/lib/client/index.js +22 -0
- package/lib/server/index.d.ts +1 -0
- package/lib/server/index.js +13 -0
- package/lib/{models → server/models}/Notification.js +4 -5
- package/package.json +20 -6
- package/server.d.ts +3 -0
- package/server.js +1 -0
- package/src/client/index.ts +7 -0
- package/src/index.ts +1 -0
- package/src/server/__tests__/notifications.test.ts +53 -0
- package/src/server/collections/notification_logs.ts +25 -0
- package/src/server/collections/notification_services.ts +25 -0
- package/src/server/collections/notifications.ts +42 -0
- package/src/server/index.ts +1 -0
- package/src/server/models/Notification.ts +85 -0
- package/src/server/models/NotificationLog.ts +3 -0
- package/src/server/models/NotificationService.ts +26 -0
- package/src/server/models/index.ts +3 -0
- package/src/server/server.ts +10 -0
- /package/lib/{collections → server/collections}/notification_logs.d.ts +0 -0
- /package/lib/{collections → server/collections}/notification_logs.js +0 -0
- /package/lib/{collections → server/collections}/notification_services.d.ts +0 -0
- /package/lib/{collections → server/collections}/notification_services.js +0 -0
- /package/lib/{collections → server/collections}/notifications.d.ts +0 -0
- /package/lib/{collections → server/collections}/notifications.js +0 -0
- /package/lib/{models → server/models}/Notification.d.ts +0 -0
- /package/lib/{models → server/models}/NotificationLog.d.ts +0 -0
- /package/lib/{models → server/models}/NotificationLog.js +0 -0
- /package/lib/{models → server/models}/NotificationService.d.ts +0 -0
- /package/lib/{models → server/models}/NotificationService.js +0 -0
- /package/lib/{models → server/models}/index.d.ts +0 -0
- /package/lib/{models → server/models}/index.js +0 -0
- /package/lib/{server.d.ts → server/server.d.ts} +0 -0
- /package/lib/{server.js → server/server.js} +0 -0
package/client.d.ts
ADDED
package/client.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib/client/index.js');
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _client() {
|
|
8
|
+
const data = require("@nocobase/client");
|
|
9
|
+
_client = function _client() {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
|
|
15
|
+
function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
|
|
16
|
+
class NotificationPlugin extends _client().Plugin {
|
|
17
|
+
load() {
|
|
18
|
+
return _asyncToGenerator(function* () {})();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
var _default = NotificationPlugin;
|
|
22
|
+
exports.default = _default;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './server';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "default", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function get() {
|
|
9
|
+
return _server.default;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
var _server = _interopRequireDefault(require("./server"));
|
|
13
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
@@ -11,14 +11,13 @@ function _database() {
|
|
|
11
11
|
};
|
|
12
12
|
return data;
|
|
13
13
|
}
|
|
14
|
-
function
|
|
15
|
-
const data =
|
|
16
|
-
|
|
14
|
+
function _utils() {
|
|
15
|
+
const data = require("@nocobase/utils");
|
|
16
|
+
_utils = function _utils() {
|
|
17
17
|
return data;
|
|
18
18
|
};
|
|
19
19
|
return data;
|
|
20
20
|
}
|
|
21
|
-
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
22
21
|
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
|
|
23
22
|
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
24
23
|
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
@@ -106,7 +105,7 @@ class Notification extends _database().Model {
|
|
|
106
105
|
return this.subject;
|
|
107
106
|
}
|
|
108
107
|
getBody(data) {
|
|
109
|
-
const compiled =
|
|
108
|
+
const compiled = _utils().lodash.template(this.body);
|
|
110
109
|
const body = compiled(data);
|
|
111
110
|
return body;
|
|
112
111
|
}
|
package/package.json
CHANGED
|
@@ -1,17 +1,31 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nocobase/plugin-notifications",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.0-alpha.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"license": "AGPL-3.0",
|
|
6
|
-
"main": "./lib/index.js",
|
|
7
|
-
"
|
|
6
|
+
"main": "./lib/server/index.js",
|
|
7
|
+
"files": [
|
|
8
|
+
"lib",
|
|
9
|
+
"src",
|
|
10
|
+
"README.md",
|
|
11
|
+
"README.zh-CN.md",
|
|
12
|
+
"CHANGELOG.md",
|
|
13
|
+
"server.js",
|
|
14
|
+
"server.d.ts",
|
|
15
|
+
"client.js",
|
|
16
|
+
"client.d.ts"
|
|
17
|
+
],
|
|
8
18
|
"dependencies": {
|
|
19
|
+
"@types/nodemailer": "6.4.4",
|
|
9
20
|
"nodemailer": "^6.6.1"
|
|
10
21
|
},
|
|
11
22
|
"devDependencies": {
|
|
12
|
-
"@nocobase/
|
|
13
|
-
"@
|
|
23
|
+
"@nocobase/client": "0.11.0-alpha.1",
|
|
24
|
+
"@nocobase/database": "0.11.0-alpha.1",
|
|
25
|
+
"@nocobase/server": "0.11.0-alpha.1",
|
|
26
|
+
"@nocobase/test": "0.11.0-alpha.1",
|
|
27
|
+
"@nocobase/utils": "0.11.0-alpha.1",
|
|
14
28
|
"nodemailer-mock": "^1.5.11"
|
|
15
29
|
},
|
|
16
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "7581b6d3a3a54f09f06a9effb7e3e65328281b2b"
|
|
17
31
|
}
|
package/server.d.ts
ADDED
package/server.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./lib/server/index.js');
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './server';
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Database from '@nocobase/database';
|
|
2
|
+
import { mockServer } from '@nocobase/test';
|
|
3
|
+
import nodemailerMock from 'nodemailer-mock';
|
|
4
|
+
import { Notification, NotificationService } from '../models';
|
|
5
|
+
import plugin from '../server';
|
|
6
|
+
|
|
7
|
+
jest.setTimeout(300000);
|
|
8
|
+
|
|
9
|
+
describe('notifications', () => {
|
|
10
|
+
let db: Database;
|
|
11
|
+
|
|
12
|
+
beforeEach(async () => {
|
|
13
|
+
const app = mockServer();
|
|
14
|
+
app.plugin(plugin);
|
|
15
|
+
await app.load();
|
|
16
|
+
db = app.db;
|
|
17
|
+
await db.sync();
|
|
18
|
+
NotificationService.createTransport = nodemailerMock.createTransport;
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
afterEach(() => db.close());
|
|
22
|
+
|
|
23
|
+
it('create', async () => {
|
|
24
|
+
const Notification = db.getCollection('notifications');
|
|
25
|
+
const notification = (await Notification.repository.create({
|
|
26
|
+
values: {
|
|
27
|
+
subject: 'Subject',
|
|
28
|
+
body: 'hell world',
|
|
29
|
+
receiver_options: {
|
|
30
|
+
data: 'to@nocobase.com',
|
|
31
|
+
fromTable: 'users',
|
|
32
|
+
filter: {},
|
|
33
|
+
dataField: 'email',
|
|
34
|
+
},
|
|
35
|
+
service: {
|
|
36
|
+
type: 'email',
|
|
37
|
+
title: '阿里云邮件推送',
|
|
38
|
+
options: {
|
|
39
|
+
host: 'smtpdm.aliyun.com',
|
|
40
|
+
port: 465,
|
|
41
|
+
secure: true,
|
|
42
|
+
auth: {
|
|
43
|
+
user: 'from@nocobase.com',
|
|
44
|
+
pass: 'pass',
|
|
45
|
+
},
|
|
46
|
+
from: 'NocoBase<from@nocobase.com>',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
})) as Notification;
|
|
51
|
+
await notification.send();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CollectionOptions } from '@nocobase/database';
|
|
2
|
+
import { NotificationLog } from '../models';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
name: 'notification_logs',
|
|
6
|
+
model: NotificationLog,
|
|
7
|
+
title: '通知日志',
|
|
8
|
+
fields: [
|
|
9
|
+
{
|
|
10
|
+
title: '接收人',
|
|
11
|
+
type: 'json',
|
|
12
|
+
name: 'receiver',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
title: '状态',
|
|
16
|
+
type: 'string',
|
|
17
|
+
name: 'state',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: '详情',
|
|
21
|
+
type: 'json',
|
|
22
|
+
name: 'response',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
} as CollectionOptions;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CollectionOptions } from '@nocobase/database';
|
|
2
|
+
import { NotificationService } from '../models';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
name: 'notification_services',
|
|
6
|
+
model: NotificationService,
|
|
7
|
+
title: '通知服务',
|
|
8
|
+
fields: [
|
|
9
|
+
{
|
|
10
|
+
title: '类型',
|
|
11
|
+
type: 'string',
|
|
12
|
+
name: 'type',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
title: '服务名称',
|
|
16
|
+
type: 'string',
|
|
17
|
+
name: 'title',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: '配置信息',
|
|
21
|
+
type: 'json',
|
|
22
|
+
name: 'options',
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
} as CollectionOptions;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { CollectionOptions } from '@nocobase/database';
|
|
2
|
+
import { Notification } from '../models';
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
name: 'notifications',
|
|
6
|
+
model: Notification,
|
|
7
|
+
title: '通知',
|
|
8
|
+
fields: [
|
|
9
|
+
{
|
|
10
|
+
type: 'uid',
|
|
11
|
+
name: 'name',
|
|
12
|
+
prefix: 'n_',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
title: '主题',
|
|
16
|
+
type: 'string',
|
|
17
|
+
name: 'subject',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
title: '内容',
|
|
21
|
+
type: 'text',
|
|
22
|
+
name: 'body',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
title: '接收人配置',
|
|
26
|
+
type: 'json',
|
|
27
|
+
name: 'receiver_options',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
title: '发送服务',
|
|
31
|
+
type: 'belongsTo',
|
|
32
|
+
name: 'service',
|
|
33
|
+
target: 'notification_services',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
title: '日志',
|
|
37
|
+
type: 'hasMany',
|
|
38
|
+
name: 'logs',
|
|
39
|
+
target: 'notification_logs',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
} as CollectionOptions;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './server';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import Database, { Model } from '@nocobase/database';
|
|
2
|
+
import { lodash } from '@nocobase/utils';
|
|
3
|
+
import { NotificationService } from './NotificationService';
|
|
4
|
+
|
|
5
|
+
export class Notification extends Model {
|
|
6
|
+
[key: string]: any;
|
|
7
|
+
|
|
8
|
+
get db(): Database {
|
|
9
|
+
return this.constructor['database'];
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async getReceiversByOptions(): Promise<any[]> {
|
|
13
|
+
const { data, fromTable, filter, dataField } = this.receiver_options;
|
|
14
|
+
let receivers = [];
|
|
15
|
+
if (data) {
|
|
16
|
+
receivers = Array.isArray(data) ? data : [data];
|
|
17
|
+
} else if (fromTable) {
|
|
18
|
+
const collection = this.db.getCollection(fromTable);
|
|
19
|
+
const rows = await collection.repository.find({
|
|
20
|
+
filter,
|
|
21
|
+
});
|
|
22
|
+
receivers = rows.map((row) => row[dataField]);
|
|
23
|
+
}
|
|
24
|
+
return receivers;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async send(options: any = {}) {
|
|
28
|
+
const { transaction } = options;
|
|
29
|
+
|
|
30
|
+
if (!this.service) {
|
|
31
|
+
this.service = await this.getService();
|
|
32
|
+
}
|
|
33
|
+
const receivers = await this.getReceiversByOptions();
|
|
34
|
+
let { to } = options;
|
|
35
|
+
if (to) {
|
|
36
|
+
to = Array.isArray(to) ? to : [to];
|
|
37
|
+
receivers.push(...to);
|
|
38
|
+
}
|
|
39
|
+
console.log(receivers);
|
|
40
|
+
for (const receiver of receivers) {
|
|
41
|
+
try {
|
|
42
|
+
const response = await (this.service as NotificationService).send({
|
|
43
|
+
to: receiver,
|
|
44
|
+
subject: this.getSubject(),
|
|
45
|
+
html: this.getBody(options),
|
|
46
|
+
});
|
|
47
|
+
await this.createLog(
|
|
48
|
+
{
|
|
49
|
+
receiver,
|
|
50
|
+
state: 'success',
|
|
51
|
+
response,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
transaction,
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
await new Promise((resolve) => {
|
|
58
|
+
setTimeout(resolve, 100);
|
|
59
|
+
});
|
|
60
|
+
} catch (error) {
|
|
61
|
+
console.error(error);
|
|
62
|
+
await this.createLog(
|
|
63
|
+
{
|
|
64
|
+
receiver,
|
|
65
|
+
state: 'fail',
|
|
66
|
+
response: {},
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
transaction,
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
getSubject() {
|
|
77
|
+
return this.subject;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
getBody(data) {
|
|
81
|
+
const compiled = lodash.template(this.body);
|
|
82
|
+
const body = compiled(data);
|
|
83
|
+
return body;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Model } from '@nocobase/database';
|
|
2
|
+
import nodemailer from 'nodemailer';
|
|
3
|
+
|
|
4
|
+
export class NotificationService extends Model {
|
|
5
|
+
[key: string]: any;
|
|
6
|
+
|
|
7
|
+
static createTransport = nodemailer.createTransport;
|
|
8
|
+
|
|
9
|
+
private _transporter = null;
|
|
10
|
+
|
|
11
|
+
get transporter() {
|
|
12
|
+
if (this._transporter) {
|
|
13
|
+
return this._transporter;
|
|
14
|
+
}
|
|
15
|
+
return (this._transporter = NotificationService.createTransport(this.options));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
async send(options) {
|
|
19
|
+
const { from } = this.options;
|
|
20
|
+
const mailOptions = {
|
|
21
|
+
from,
|
|
22
|
+
...options,
|
|
23
|
+
};
|
|
24
|
+
return this.transporter.sendMail(mailOptions);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|