streamby-core 0.26.1 → 0.26.3
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/dist/index.d.ts +2 -0
- package/dist/index.js +5 -1
- package/dist/middleware/createRouter.js +10 -0
- package/dist/middleware/routes/connection.js +5 -5
- package/dist/middleware/routes/notification.d.ts +3 -0
- package/dist/middleware/routes/notification.js +44 -0
- package/dist/services/apiConnection.d.ts +1 -1
- package/dist/services/apiConnection.js +1 -1
- package/dist/services/notification.d.ts +1 -0
- package/dist/services/notification.js +21 -0
- package/dist/services/pipeline.js +1 -1
- package/dist/services/wsHub.d.ts +4 -0
- package/dist/services/wsHub.js +43 -0
- package/dist/types/index.d.ts +17 -1
- package/package.json +4 -2
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.createStreamByRouter = void 0;
|
|
3
|
+
exports.createNotification = exports.emitToUser = exports.createStreamByRouter = void 0;
|
|
4
4
|
var createRouter_1 = require("./middleware/createRouter");
|
|
5
5
|
Object.defineProperty(exports, "createStreamByRouter", { enumerable: true, get: function () { return createRouter_1.createStreamByRouter; } });
|
|
6
|
+
var wsHub_1 = require("./services/wsHub");
|
|
7
|
+
Object.defineProperty(exports, "emitToUser", { enumerable: true, get: function () { return wsHub_1.emitToUser; } });
|
|
8
|
+
var notification_1 = require("./services/notification");
|
|
9
|
+
Object.defineProperty(exports, "createNotification", { enumerable: true, get: function () { return notification_1.createNotification; } });
|
|
@@ -17,8 +17,10 @@ const credential_1 = require("./routes/credential");
|
|
|
17
17
|
const connection_1 = require("./routes/connection");
|
|
18
18
|
const member_1 = require("./routes/member");
|
|
19
19
|
const user_1 = require("./routes/user");
|
|
20
|
+
const notification_1 = require("./routes/notification");
|
|
20
21
|
const auth_2 = require("../services/auth");
|
|
21
22
|
const encryption_1 = require("../utils/encryption");
|
|
23
|
+
const wsHub_1 = require("../services/wsHub");
|
|
22
24
|
function createStreamByRouter(config) {
|
|
23
25
|
const router = express_1.default.Router();
|
|
24
26
|
if (config.encrypt)
|
|
@@ -31,11 +33,18 @@ function createStreamByRouter(config) {
|
|
|
31
33
|
const streambySchema = sqlDbs.length > 0 ? 'streamby' : undefined;
|
|
32
34
|
(0, manager_1.registerModel)('projects', allDbIds, 'projects', streambySchema);
|
|
33
35
|
(0, manager_1.registerModel)('exports', allDbIds, 'exports', streambySchema);
|
|
36
|
+
const nosqlDbIds = config.databases.filter(db => db.type === 'nosql').map(db => db.id);
|
|
37
|
+
if (nosqlDbIds.length > 0) {
|
|
38
|
+
(0, manager_1.registerModel)('notifications', nosqlDbIds, 'notifications');
|
|
39
|
+
}
|
|
34
40
|
const mainDb = config.databases.find(db => db.main);
|
|
35
41
|
if (mainDb) {
|
|
36
42
|
(0, manager_1.registerModel)('users', [mainDb.id], 'users', 'accounts');
|
|
37
43
|
}
|
|
38
44
|
}
|
|
45
|
+
if (config.websocket?.server) {
|
|
46
|
+
(0, wsHub_1.initWsHub)(config.websocket.server, config, config.websocket.path);
|
|
47
|
+
}
|
|
39
48
|
router.use((0, auth_2.authenticate)(config));
|
|
40
49
|
router.use((0, auth_1.authRouter)(config));
|
|
41
50
|
router.use((0, database_1.databaseRouter)(config));
|
|
@@ -46,5 +55,6 @@ function createStreamByRouter(config) {
|
|
|
46
55
|
router.use((0, connection_1.apiConnectionRouter)(config));
|
|
47
56
|
router.use((0, member_1.memberRouter)(config));
|
|
48
57
|
router.use((0, user_1.userRouter)(config));
|
|
58
|
+
router.use((0, notification_1.notificationRouter)(config));
|
|
49
59
|
return router;
|
|
50
60
|
}
|
|
@@ -68,9 +68,9 @@ function apiConnectionRouter(config) {
|
|
|
68
68
|
return res.status(403).json({ message: 'Permission denied' });
|
|
69
69
|
}
|
|
70
70
|
const projectId = req.params.id;
|
|
71
|
-
const { name,
|
|
72
|
-
if (!name || !
|
|
73
|
-
return res.status(400).json({ message: 'name and
|
|
71
|
+
const { name, apiUrl, method, description, credentialId, prefix } = req.body;
|
|
72
|
+
if (!name || !apiUrl) {
|
|
73
|
+
return res.status(400).json({ message: 'name and apiUrl are required' });
|
|
74
74
|
}
|
|
75
75
|
if (!VALID_METHODS.includes(method)) {
|
|
76
76
|
return res.status(400).json({ message: `method must be one of: ${VALID_METHODS.join(', ')}` });
|
|
@@ -90,7 +90,7 @@ function apiConnectionRouter(config) {
|
|
|
90
90
|
}
|
|
91
91
|
const connection = await (0, apiConnection_1.addApiConnection)(config, projectId, {
|
|
92
92
|
name,
|
|
93
|
-
|
|
93
|
+
apiUrl,
|
|
94
94
|
method,
|
|
95
95
|
prefix,
|
|
96
96
|
...(description !== undefined && { description }),
|
|
@@ -132,7 +132,7 @@ function apiConnectionRouter(config) {
|
|
|
132
132
|
const prefix = apiConnection.prefix ? `${apiConnection.prefix} ` : '';
|
|
133
133
|
headers['Authorization'] = `${prefix}${decrypted}`;
|
|
134
134
|
}
|
|
135
|
-
const response = await fetch(apiConnection.
|
|
135
|
+
const response = await fetch(apiConnection.apiUrl, { method: apiConnection.method || 'GET', headers });
|
|
136
136
|
if (!response.ok) {
|
|
137
137
|
return res.status(response.status).json({ message: `External API error: ${response.statusText}` });
|
|
138
138
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.notificationRouter = notificationRouter;
|
|
4
|
+
const express_1 = require("express");
|
|
5
|
+
const manager_1 = require("../../models/manager");
|
|
6
|
+
function notificationRouter(config) {
|
|
7
|
+
const router = (0, express_1.Router)();
|
|
8
|
+
const Notification = (0, manager_1.getModel)('notifications');
|
|
9
|
+
router.get('/notifications', async (req, res) => {
|
|
10
|
+
try {
|
|
11
|
+
const auth = req.auth;
|
|
12
|
+
const notifications = await Notification.find({ userId: auth.userId, read: false });
|
|
13
|
+
res.status(200).json({ data: notifications });
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
res.status(500).json({ message: 'Failed to fetch notifications', details: err.message });
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
router.patch('/notifications/read-all', async (req, res) => {
|
|
20
|
+
try {
|
|
21
|
+
const auth = req.auth;
|
|
22
|
+
const model = Notification;
|
|
23
|
+
if (model.updateMany) {
|
|
24
|
+
await model.updateMany({ userId: auth.userId, read: false }, { $set: { read: true, readAt: new Date() } });
|
|
25
|
+
}
|
|
26
|
+
res.status(200).json({ message: 'All notifications marked as read' });
|
|
27
|
+
}
|
|
28
|
+
catch (err) {
|
|
29
|
+
res.status(500).json({ message: 'Failed to update notifications', details: err.message });
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
router.patch('/notifications/:id/read', async (req, res) => {
|
|
33
|
+
try {
|
|
34
|
+
const auth = req.auth;
|
|
35
|
+
const { id } = req.params;
|
|
36
|
+
await Notification.update({ _id: id, userId: auth.userId }, { read: true, readAt: new Date() });
|
|
37
|
+
res.status(200).json({ message: 'Notification marked as read' });
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
res.status(500).json({ message: 'Failed to update notification', details: err.message });
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
return router;
|
|
44
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { StreamByConfig, ApiConnection, ApiConnectionMethod } from '../types';
|
|
2
2
|
export declare function addApiConnection(config: StreamByConfig, projectId: string, data: {
|
|
3
3
|
name: string;
|
|
4
|
-
|
|
4
|
+
apiUrl: string;
|
|
5
5
|
method: ApiConnectionMethod;
|
|
6
6
|
prefix?: string;
|
|
7
7
|
description?: string;
|
|
@@ -14,7 +14,7 @@ async function addApiConnection(config, projectId, data) {
|
|
|
14
14
|
id: new mongodb_1.ObjectId().toHexString(),
|
|
15
15
|
name: data.name,
|
|
16
16
|
prefix: data.prefix,
|
|
17
|
-
|
|
17
|
+
apiUrl: data.apiUrl,
|
|
18
18
|
method: data.method,
|
|
19
19
|
projectId,
|
|
20
20
|
createdAt: new Date(),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createNotification(userId: string, type: string, message: string, data?: any, appId?: string, callback?: string): Promise<any>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createNotification = createNotification;
|
|
4
|
+
const manager_1 = require("../models/manager");
|
|
5
|
+
const wsHub_1 = require("./wsHub");
|
|
6
|
+
async function createNotification(userId, type, message, data, appId, callback) {
|
|
7
|
+
const Notification = (0, manager_1.getModel)('notifications');
|
|
8
|
+
const notification = await Notification.create({
|
|
9
|
+
userId,
|
|
10
|
+
appId: appId ?? null,
|
|
11
|
+
type,
|
|
12
|
+
message,
|
|
13
|
+
data: data ?? null,
|
|
14
|
+
callback: callback ?? null,
|
|
15
|
+
read: false,
|
|
16
|
+
readAt: null,
|
|
17
|
+
createdAt: new Date(),
|
|
18
|
+
});
|
|
19
|
+
(0, wsHub_1.emitToUser)(userId, { type: 'notification', data: notification });
|
|
20
|
+
return notification;
|
|
21
|
+
}
|
|
@@ -53,7 +53,7 @@ async function executePipeline(nodeSchema, project, config) {
|
|
|
53
53
|
headers['Authorization'] = `${prefix}${decrypted}`;
|
|
54
54
|
}
|
|
55
55
|
}
|
|
56
|
-
const response = await fetch(apiConnection.
|
|
56
|
+
const response = await fetch(apiConnection.apiUrl, { method: apiConnection.method || 'GET', headers });
|
|
57
57
|
if (!response.ok)
|
|
58
58
|
throw new Error(`API connection fetch failed: ${response.statusText}`);
|
|
59
59
|
dataResults.push(await response.json());
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initWsHub = initWsHub;
|
|
4
|
+
exports.emitToUser = emitToUser;
|
|
5
|
+
const ws_1 = require("ws");
|
|
6
|
+
const connections = new Map();
|
|
7
|
+
function initWsHub(server, config, path = '/streamby/ws') {
|
|
8
|
+
const wss = new ws_1.WebSocketServer({ server, path });
|
|
9
|
+
wss.on('connection', async (ws, req) => {
|
|
10
|
+
let userId = null;
|
|
11
|
+
try {
|
|
12
|
+
const auth = await config.authProvider(req);
|
|
13
|
+
if (!auth?.userId) {
|
|
14
|
+
ws.close(1008, 'Unauthorized');
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
userId = auth.userId;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
ws.close(1008, 'Unauthorized');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (!connections.has(userId))
|
|
24
|
+
connections.set(userId, new Set());
|
|
25
|
+
connections.get(userId).add(ws);
|
|
26
|
+
ws.on('close', () => {
|
|
27
|
+
connections.get(userId)?.delete(ws);
|
|
28
|
+
if (connections.get(userId)?.size === 0)
|
|
29
|
+
connections.delete(userId);
|
|
30
|
+
});
|
|
31
|
+
ws.send(JSON.stringify({ type: 'connected', userId }));
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
function emitToUser(userId, event) {
|
|
35
|
+
const userConnections = connections.get(userId);
|
|
36
|
+
if (!userConnections)
|
|
37
|
+
return;
|
|
38
|
+
const payload = JSON.stringify(event);
|
|
39
|
+
for (const ws of userConnections) {
|
|
40
|
+
if (ws.readyState === ws_1.WebSocket.OPEN)
|
|
41
|
+
ws.send(payload);
|
|
42
|
+
}
|
|
43
|
+
}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -68,7 +68,7 @@ export type ApiConnectionMethod = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
|
|
|
68
68
|
export interface ApiConnection {
|
|
69
69
|
id: string;
|
|
70
70
|
name: string;
|
|
71
|
-
|
|
71
|
+
apiUrl: string;
|
|
72
72
|
method: ApiConnectionMethod;
|
|
73
73
|
projectId: string;
|
|
74
74
|
createdAt: Date;
|
|
@@ -99,6 +99,22 @@ export interface StreamByConfig {
|
|
|
99
99
|
databases?: DatabaseCredential[];
|
|
100
100
|
adapter?: StorageAdapter;
|
|
101
101
|
encrypt?: string;
|
|
102
|
+
websocket?: {
|
|
103
|
+
server: any;
|
|
104
|
+
path?: string;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export interface Notification {
|
|
108
|
+
_id?: string;
|
|
109
|
+
userId: string;
|
|
110
|
+
appId?: string;
|
|
111
|
+
type: string;
|
|
112
|
+
message: string;
|
|
113
|
+
data?: any;
|
|
114
|
+
callback?: string;
|
|
115
|
+
read: boolean;
|
|
116
|
+
readAt?: Date;
|
|
117
|
+
createdAt: Date;
|
|
102
118
|
}
|
|
103
119
|
export interface Auth {
|
|
104
120
|
userId: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "streamby-core",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.3",
|
|
4
4
|
"description": "StreamBy middleware framework for media storage management",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -37,9 +37,10 @@
|
|
|
37
37
|
"express": "^4.0.0",
|
|
38
38
|
"mongodb": "^6.17.0",
|
|
39
39
|
"mongoose": "^8.13.2",
|
|
40
|
+
"node-fetch": "^3.0.0",
|
|
40
41
|
"pg": "^8.16.3",
|
|
41
42
|
"prisma": "^6.12.0",
|
|
42
|
-
"
|
|
43
|
+
"ws": "^8.20.0"
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@types/bcrypt": "^5.0.2",
|
|
@@ -49,6 +50,7 @@
|
|
|
49
50
|
"@types/node": "^22.15.21",
|
|
50
51
|
"@types/pg": "^8.15.4",
|
|
51
52
|
"@types/supertest": "^6.0.3",
|
|
53
|
+
"@types/ws": "^8.18.1",
|
|
52
54
|
"cors": "^2.8.5",
|
|
53
55
|
"supertest": "^7.1.4",
|
|
54
56
|
"ts-node-dev": "^2.0.0",
|