mira-app-core 1.0.0
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/HttpRouter.d.ts +17 -0
- package/dist/HttpRouter.d.ts.map +1 -0
- package/dist/HttpRouter.js +217 -0
- package/dist/HttpRouter.js.map +1 -0
- package/dist/HttpServer.d.ts +24 -0
- package/dist/HttpServer.d.ts.map +1 -0
- package/dist/HttpServer.js +55 -0
- package/dist/HttpServer.js.map +1 -0
- package/dist/ILibraryServerData.d.ts +63 -0
- package/dist/ILibraryServerData.d.ts.map +1 -0
- package/dist/ILibraryServerData.js +3 -0
- package/dist/ILibraryServerData.js.map +1 -0
- package/dist/LibraryList.d.ts +9 -0
- package/dist/LibraryList.d.ts.map +1 -0
- package/dist/LibraryList.js +29 -0
- package/dist/LibraryList.js.map +1 -0
- package/dist/LibraryServerDataSQLite.d.ts +96 -0
- package/dist/LibraryServerDataSQLite.d.ts.map +1 -0
- package/dist/LibraryServerDataSQLite.js +683 -0
- package/dist/LibraryServerDataSQLite.js.map +1 -0
- package/dist/LibraryStorage.d.ts +14 -0
- package/dist/LibraryStorage.d.ts.map +1 -0
- package/dist/LibraryStorage.js +45 -0
- package/dist/LibraryStorage.js.map +1 -0
- package/dist/MessageHandler.d.ts +16 -0
- package/dist/MessageHandler.d.ts.map +1 -0
- package/dist/MessageHandler.js +35 -0
- package/dist/MessageHandler.js.map +1 -0
- package/dist/ServerExample.d.ts +33 -0
- package/dist/ServerExample.d.ts.map +1 -0
- package/dist/ServerExample.js +87 -0
- package/dist/ServerExample.js.map +1 -0
- package/dist/ServerPlugin.d.ts +20 -0
- package/dist/ServerPlugin.d.ts.map +1 -0
- package/dist/ServerPlugin.js +79 -0
- package/dist/ServerPlugin.js.map +1 -0
- package/dist/ServerPluginManager.d.ts +30 -0
- package/dist/ServerPluginManager.d.ts.map +1 -0
- package/dist/ServerPluginManager.js +112 -0
- package/dist/ServerPluginManager.js.map +1 -0
- package/dist/WebSocketRouter.d.ts +18 -0
- package/dist/WebSocketRouter.d.ts.map +1 -0
- package/dist/WebSocketRouter.js +31 -0
- package/dist/WebSocketRouter.js.map +1 -0
- package/dist/WebSocketServer.d.ts +23 -0
- package/dist/WebSocketServer.d.ts.map +1 -0
- package/dist/WebSocketServer.js +162 -0
- package/dist/WebSocketServer.js.map +1 -0
- package/dist/event-manager.d.ts +85 -0
- package/dist/event-manager.d.ts.map +1 -0
- package/dist/event-manager.js +142 -0
- package/dist/event-manager.js.map +1 -0
- package/dist/handlers/FileHandler.d.ts +10 -0
- package/dist/handlers/FileHandler.d.ts.map +1 -0
- package/dist/handlers/FileHandler.js +55 -0
- package/dist/handlers/FileHandler.js.map +1 -0
- package/dist/handlers/FolderHandler.d.ts +10 -0
- package/dist/handlers/FolderHandler.d.ts.map +1 -0
- package/dist/handlers/FolderHandler.js +59 -0
- package/dist/handlers/FolderHandler.js.map +1 -0
- package/dist/handlers/LibraryHandler.d.ts +10 -0
- package/dist/handlers/LibraryHandler.d.ts.map +1 -0
- package/dist/handlers/LibraryHandler.js +49 -0
- package/dist/handlers/LibraryHandler.js.map +1 -0
- package/dist/handlers/MessageHandler.d.ts +15 -0
- package/dist/handlers/MessageHandler.d.ts.map +1 -0
- package/dist/handlers/MessageHandler.js +32 -0
- package/dist/handlers/MessageHandler.js.map +1 -0
- package/dist/handlers/PluginMessageHandler.d.ts +10 -0
- package/dist/handlers/PluginMessageHandler.d.ts.map +1 -0
- package/dist/handlers/PluginMessageHandler.js +21 -0
- package/dist/handlers/PluginMessageHandler.js.map +1 -0
- package/dist/handlers/TagHandler.d.ts +10 -0
- package/dist/handlers/TagHandler.d.ts.map +1 -0
- package/dist/handlers/TagHandler.js +59 -0
- package/dist/handlers/TagHandler.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +58 -0
- package/dist/index.js.map +1 -0
- package/package.json +32 -0
- package/src/HttpRouter.ts +236 -0
- package/src/HttpServer.ts +72 -0
- package/src/ILibraryServerData.ts +70 -0
- package/src/LibraryList.ts +26 -0
- package/src/LibraryServerDataSQLite.ts +778 -0
- package/src/LibraryStorage.ts +55 -0
- package/src/MessageHandler.ts +41 -0
- package/src/ServerExample.ts +72 -0
- package/src/ServerPlugin.ts +56 -0
- package/src/ServerPluginManager.ts +106 -0
- package/src/WebSocketRouter.ts +46 -0
- package/src/WebSocketServer.ts +206 -0
- package/src/event-manager.ts +191 -0
- package/src/handlers/FileHandler.ts +61 -0
- package/src/handlers/FolderHandler.ts +65 -0
- package/src/handlers/LibraryHandler.ts +55 -0
- package/src/handlers/MessageHandler.ts +37 -0
- package/src/handlers/PluginMessageHandler.ts +27 -0
- package/src/handlers/TagHandler.ts +66 -0
- package/src/index.ts +44 -0
- package/tsconfig.json +23 -0
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LibraryHandler = void 0;
|
|
4
|
+
const MessageHandler_1 = require("./MessageHandler");
|
|
5
|
+
class LibraryHandler extends MessageHandler_1.MessageHandler {
|
|
6
|
+
constructor(server, dbService, ws, message) {
|
|
7
|
+
super(server, dbService, ws, message);
|
|
8
|
+
}
|
|
9
|
+
async handle() {
|
|
10
|
+
try {
|
|
11
|
+
const { action, payload } = this.message;
|
|
12
|
+
const { data } = payload;
|
|
13
|
+
const libraryId = this.dbService.getLibraryId();
|
|
14
|
+
let result;
|
|
15
|
+
switch (action) {
|
|
16
|
+
case 'open':
|
|
17
|
+
// 初次握手,发送服务器所需字段信息
|
|
18
|
+
this.server.sendToWebsocket(this.ws, { eventName: 'try_connect', data: {
|
|
19
|
+
fields: this.dbService.pluginManager.fields, // 所有插件所需字段信息
|
|
20
|
+
} });
|
|
21
|
+
break;
|
|
22
|
+
case 'connect':
|
|
23
|
+
// 第二次握手
|
|
24
|
+
this.server.broadcastPluginEvent('client::before_connect', {
|
|
25
|
+
message: this.message,
|
|
26
|
+
ws: this.ws,
|
|
27
|
+
}).then(async (ok) => {
|
|
28
|
+
if (ok) {
|
|
29
|
+
const data = await this.dbService.getLibraryInfo(); // 获取所有标签,文件夹等信息
|
|
30
|
+
this.server.sendToWebsocket(this.ws, { eventName: 'connected', data: data });
|
|
31
|
+
this.server.broadcastPluginEvent('client::connected', { libraryId });
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
break;
|
|
35
|
+
case 'close':
|
|
36
|
+
result = await this.dbService.closeLibrary();
|
|
37
|
+
break;
|
|
38
|
+
default:
|
|
39
|
+
throw new Error(`Unsupported library action: ${action}`);
|
|
40
|
+
}
|
|
41
|
+
this.sendResponse({});
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
this.sendError(err instanceof Error ? err.message : 'Library operation failed');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.LibraryHandler = LibraryHandler;
|
|
49
|
+
//# sourceMappingURL=LibraryHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LibraryHandler.js","sourceRoot":"","sources":["../../src/handlers/LibraryHandler.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAMlD,MAAa,cAAe,SAAQ,+BAAc;IAChD,YACE,MAA2B,EAC3B,SAAkC,EAClC,EAAa,EACb,OAAyB;QAEzB,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YACzC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;YACzB,MAAM,SAAS,GAAI,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;YACjD,IAAI,MAAM,CAAC;YACX,QAAO,MAAM,EAAE,CAAC;gBACd,KAAK,MAAM;oBACT,mBAAmB;oBACnB,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,EAAE;4BACrE,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,aAAc,CAAC,MAAM,EAAE,aAAa;yBAC5D,EAAC,CAAC,CAAC;oBACJ,MAAM;gBACR,KAAK,SAAS;oBACZ,SAAS;oBACT,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,wBAAwB,EAAE;wBACzD,OAAO,EAAE,IAAI,CAAC,OAAO;wBACrB,EAAE,EAAE,IAAI,CAAC,EAAE;qBACZ,CAAC,CAAC,IAAI,CAAC,KAAK,EAAC,EAAE,EAAC,EAAE;wBACjB,IAAG,EAAE,EAAC,CAAC;4BACL,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,cAAc,EAAE,CAAC,CAAC,gBAAgB;4BACpE,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;4BAC7E,IAAI,CAAC,MAAM,CAAC,oBAAoB,CAAC,mBAAmB,EAAE,EAAE,SAAS,EAAE,CAAC,CAAC;wBACvE,CAAC;oBACH,CAAC,CAAC,CAAC;oBACH,MAAM;gBACR,KAAK,OAAO;oBACV,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;oBAC7C,MAAM;gBACR;oBACE,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,EAAE,CAAC,CAAC;YAC7D,CAAC;YAED,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,SAAS,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC;QAClF,CAAC;IACH,CAAC;CACF;AAhDD,wCAgDC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { LibraryServerDataSQLite } from '../LibraryServerDataSQLite';
|
|
2
|
+
import { WebSocket } from 'ws';
|
|
3
|
+
import { WebSocketMessage } from '../WebSocketRouter';
|
|
4
|
+
import { MiraWebsocketServer } from '../WebSocketServer';
|
|
5
|
+
export declare abstract class MessageHandler {
|
|
6
|
+
protected server: MiraWebsocketServer;
|
|
7
|
+
protected dbService: LibraryServerDataSQLite;
|
|
8
|
+
protected ws: WebSocket;
|
|
9
|
+
protected message: WebSocketMessage;
|
|
10
|
+
constructor(server: MiraWebsocketServer, dbService: LibraryServerDataSQLite, ws: WebSocket, message: WebSocketMessage);
|
|
11
|
+
abstract handle(): Promise<void>;
|
|
12
|
+
protected sendResponse(data: Record<string, any>): void;
|
|
13
|
+
protected sendError(error: string): void;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=MessageHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/MessageHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,SAAS,EAAmB,MAAM,IAAI,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,8BAAsB,cAAc;IAEhC,SAAS,CAAC,MAAM,EAAE,mBAAmB;IACrC,SAAS,CAAC,SAAS,EAAE,uBAAuB;IAC5C,SAAS,CAAC,EAAE,EAAE,SAAS;IACvB,SAAS,CAAC,OAAO,EAAE,gBAAgB;gBAHzB,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,uBAAuB,EAClC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,gBAAgB;IAGrC,QAAQ,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAEhC,SAAS,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;IAWvD,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CASzC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MessageHandler = void 0;
|
|
4
|
+
class MessageHandler {
|
|
5
|
+
constructor(server, dbService, ws, message) {
|
|
6
|
+
this.server = server;
|
|
7
|
+
this.dbService = dbService;
|
|
8
|
+
this.ws = ws;
|
|
9
|
+
this.message = message;
|
|
10
|
+
}
|
|
11
|
+
sendResponse(data) {
|
|
12
|
+
const response = JSON.stringify({
|
|
13
|
+
'requestId': this.message.requestId,
|
|
14
|
+
'libraryId': this.message.libraryId,
|
|
15
|
+
"status": "success",
|
|
16
|
+
data,
|
|
17
|
+
});
|
|
18
|
+
console.log({ response });
|
|
19
|
+
this.ws.send(response);
|
|
20
|
+
}
|
|
21
|
+
sendError(error) {
|
|
22
|
+
const response = JSON.stringify({
|
|
23
|
+
...this.message,
|
|
24
|
+
status: 'error',
|
|
25
|
+
error
|
|
26
|
+
});
|
|
27
|
+
console.log({ response });
|
|
28
|
+
this.ws.send(response);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
exports.MessageHandler = MessageHandler;
|
|
32
|
+
//# sourceMappingURL=MessageHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageHandler.js","sourceRoot":"","sources":["../../src/handlers/MessageHandler.ts"],"names":[],"mappings":";;;AAMA,MAAsB,cAAc;IAClC,YACY,MAA2B,EAC3B,SAAkC,EAClC,EAAa,EACb,OAAyB;QAHzB,WAAM,GAAN,MAAM,CAAqB;QAC3B,cAAS,GAAT,SAAS,CAAyB;QAClC,OAAE,GAAF,EAAE,CAAW;QACb,YAAO,GAAP,OAAO,CAAkB;IAClC,CAAC;IAIM,YAAY,CAAC,IAAyB;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;YAC9B,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACnC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS;YACnC,QAAQ,EAAC,SAAS;YAClB,IAAI;SACL,CAAC,CAAA;QACF,OAAO,CAAC,GAAG,CAAC,EAAC,QAAQ,EAAC,CAAC,CAAC;QACxB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;IAES,SAAS,CAAC,KAAa;QAC/B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;YAC9B,GAAG,IAAI,CAAC,OAAO;YACf,MAAM,EAAE,OAAO;YACf,KAAK;SACN,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,CAAC,EAAC,QAAQ,EAAC,CAAC,CAAA;QACvB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzB,CAAC;CACF;AA9BD,wCA8BC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MessageHandler } from './MessageHandler';
|
|
2
|
+
import { WebSocket } from 'ws';
|
|
3
|
+
import { WebSocketMessage } from '../WebSocketRouter';
|
|
4
|
+
import { LibraryServerDataSQLite } from '../LibraryServerDataSQLite';
|
|
5
|
+
import { MiraWebsocketServer } from '../WebSocketServer';
|
|
6
|
+
export declare class PluginMessageHandler extends MessageHandler {
|
|
7
|
+
constructor(server: MiraWebsocketServer, dbService: LibraryServerDataSQLite, ws: WebSocket, message: WebSocketMessage);
|
|
8
|
+
handle(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=PluginMessageHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginMessageHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/PluginMessageHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,qBAAa,oBAAqB,SAAQ,cAAc;gBAEpD,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,uBAAuB,EAClC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,gBAAgB;IAKrB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAU9B"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PluginMessageHandler = void 0;
|
|
4
|
+
const MessageHandler_1 = require("./MessageHandler");
|
|
5
|
+
class PluginMessageHandler extends MessageHandler_1.MessageHandler {
|
|
6
|
+
constructor(server, dbService, ws, message) {
|
|
7
|
+
super(server, dbService, ws, message);
|
|
8
|
+
}
|
|
9
|
+
async handle() {
|
|
10
|
+
try {
|
|
11
|
+
const { action, payload } = this.message;
|
|
12
|
+
const { data } = payload;
|
|
13
|
+
// this.server.broadcastPluginEvent('plugin::connected', { ws: this.ws, fields: data['fields'] });
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
this.sendError(err instanceof Error ? err.message : 'PluginMessageHandler failed');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.PluginMessageHandler = PluginMessageHandler;
|
|
21
|
+
//# sourceMappingURL=PluginMessageHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PluginMessageHandler.js","sourceRoot":"","sources":["../../src/handlers/PluginMessageHandler.ts"],"names":[],"mappings":";;;AAAA,qDAAkD;AAMlD,MAAa,oBAAqB,SAAQ,+BAAc;IACtD,YACE,MAA2B,EAC3B,SAAkC,EAClC,EAAa,EACb,OAAyB;QAEzB,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC;YACH,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC;YACzC,MAAM,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;YAEzB,kGAAkG;QACpG,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,SAAS,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,6BAA6B,CAAC,CAAC;QACrF,CAAC;IACH,CAAC;CACF;AApBD,oDAoBC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { MessageHandler } from './MessageHandler';
|
|
2
|
+
import { WebSocket } from 'ws';
|
|
3
|
+
import { WebSocketMessage } from '../WebSocketRouter';
|
|
4
|
+
import { LibraryServerDataSQLite } from '../LibraryServerDataSQLite';
|
|
5
|
+
import { MiraWebsocketServer } from '../WebSocketServer';
|
|
6
|
+
export declare class TagHandler extends MessageHandler {
|
|
7
|
+
constructor(server: MiraWebsocketServer, dbService: LibraryServerDataSQLite, ws: WebSocket, message: WebSocketMessage);
|
|
8
|
+
handle(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=TagHandler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagHandler.d.ts","sourceRoot":"","sources":["../../src/handlers/TagHandler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AACrE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,qBAAa,UAAW,SAAQ,cAAc;gBAE1C,MAAM,EAAE,mBAAmB,EAC3B,SAAS,EAAE,uBAAuB,EAClC,EAAE,EAAE,SAAS,EACb,OAAO,EAAE,gBAAgB;IAKrB,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;CAiD9B"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TagHandler = void 0;
|
|
4
|
+
const MessageHandler_1 = require("./MessageHandler");
|
|
5
|
+
class TagHandler extends MessageHandler_1.MessageHandler {
|
|
6
|
+
constructor(server, dbService, ws, message) {
|
|
7
|
+
super(server, dbService, ws, message);
|
|
8
|
+
}
|
|
9
|
+
async handle() {
|
|
10
|
+
try {
|
|
11
|
+
const { action, payload } = this.message;
|
|
12
|
+
const { data } = payload;
|
|
13
|
+
const libraryId = this.dbService.getLibraryId();
|
|
14
|
+
let result;
|
|
15
|
+
switch (action) {
|
|
16
|
+
case 'file_set':
|
|
17
|
+
var { fileId, tags } = data;
|
|
18
|
+
if (await this.dbService.setFileTags(fileId, tags)) {
|
|
19
|
+
result = { fileId, tags, libraryId };
|
|
20
|
+
this.server.broadcastPluginEvent('file::setTag', result);
|
|
21
|
+
this.server.broadcastLibraryEvent(libraryId, 'file::setTag', result);
|
|
22
|
+
}
|
|
23
|
+
break;
|
|
24
|
+
case 'file_get':
|
|
25
|
+
var { fileId } = data;
|
|
26
|
+
result = { tags: await this.dbService.getFileTags(fileId) };
|
|
27
|
+
break;
|
|
28
|
+
case 'all':
|
|
29
|
+
result = await this.dbService.getAllTags();
|
|
30
|
+
break;
|
|
31
|
+
case 'read':
|
|
32
|
+
result = await this.dbService.queryTag(data.query);
|
|
33
|
+
break;
|
|
34
|
+
case 'create':
|
|
35
|
+
result = await this.dbService.createTag(data);
|
|
36
|
+
break;
|
|
37
|
+
case 'update':
|
|
38
|
+
result = await this.dbService.updateTag(data.id, data);
|
|
39
|
+
break;
|
|
40
|
+
case 'delete':
|
|
41
|
+
var { id } = data;
|
|
42
|
+
if (await this.dbService.deleteTag(data.id)) {
|
|
43
|
+
result = { id };
|
|
44
|
+
this.server.broadcastPluginEvent('tag::deleted', { id, libraryId });
|
|
45
|
+
this.server.sendToWebsocket(this.ws, { eventName: 'file::deleted', data: { id, libraryId } });
|
|
46
|
+
}
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(`Unsupported tag action: ${action}`);
|
|
50
|
+
}
|
|
51
|
+
this.sendResponse(result);
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
this.sendError(err instanceof Error ? err.message : 'Tag operation failed');
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.TagHandler = TagHandler;
|
|
59
|
+
//# sourceMappingURL=TagHandler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagHandler.js","sourceRoot":"","sources":["../../src/handlers/TagHandler.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @hunmer/mira-core - Core library for Mira TypeScript project
|
|
3
|
+
*
|
|
4
|
+
* This is an import-only library. No code is automatically executed when importing.
|
|
5
|
+
* All classes and functions must be explicitly instantiated/called by the consuming code.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* // Import specific classes/functions as needed
|
|
9
|
+
* import { MiraBackend, MiraWebsocketServer } from '@hunmer/mira-core';
|
|
10
|
+
*
|
|
11
|
+
* // Create instances manually when needed
|
|
12
|
+
* const backend = new MiraBackend({ autoStart: false });
|
|
13
|
+
* // or use the static factory method to auto-start
|
|
14
|
+
* const backend = MiraBackend.createAndStart();
|
|
15
|
+
*/
|
|
16
|
+
export { ILibraryServerData } from './ILibraryServerData';
|
|
17
|
+
export { MiraWebsocketServer } from './WebSocketServer';
|
|
18
|
+
export { MiraHttpServer } from './HttpServer';
|
|
19
|
+
export { ServerPluginManager, PluginConfig } from './ServerPluginManager';
|
|
20
|
+
export { EventArgs, EventSubscription, EventManager } from './event-manager';
|
|
21
|
+
export { getLibrarysJson } from './LibraryList';
|
|
22
|
+
export { LibraryServerDataSQLite } from './LibraryServerDataSQLite';
|
|
23
|
+
export { LibraryStorage } from './LibraryStorage';
|
|
24
|
+
export { MessageHandler } from './MessageHandler';
|
|
25
|
+
export { ServerPlugin } from './ServerPlugin';
|
|
26
|
+
export { HttpRouter } from './HttpRouter';
|
|
27
|
+
export { WebSocketRouter, WebSocketMessage } from './WebSocketRouter';
|
|
28
|
+
export { MiraBackend } from './ServerExample';
|
|
29
|
+
export { FileHandler } from './handlers/FileHandler';
|
|
30
|
+
export { FolderHandler } from './handlers/FolderHandler';
|
|
31
|
+
export { LibraryHandler } from './handlers/LibraryHandler';
|
|
32
|
+
export { MessageHandler as HandlerMessageHandler } from './handlers/MessageHandler';
|
|
33
|
+
export { PluginMessageHandler } from './handlers/PluginMessageHandler';
|
|
34
|
+
export { TagHandler } from './handlers/TagHandler';
|
|
35
|
+
export type * from './ILibraryServerData';
|
|
36
|
+
export type * from './event-manager';
|
|
37
|
+
export type * from './ServerPluginManager';
|
|
38
|
+
export type * from './WebSocketRouter';
|
|
39
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7E,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACtE,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,cAAc,IAAI,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AACpF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAGnD,mBAAmB,sBAAsB,CAAC;AAC1C,mBAAmB,iBAAiB,CAAC;AACrC,mBAAmB,uBAAuB,CAAC;AAC3C,mBAAmB,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @hunmer/mira-core - Core library for Mira TypeScript project
|
|
4
|
+
*
|
|
5
|
+
* This is an import-only library. No code is automatically executed when importing.
|
|
6
|
+
* All classes and functions must be explicitly instantiated/called by the consuming code.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Import specific classes/functions as needed
|
|
10
|
+
* import { MiraBackend, MiraWebsocketServer } from '@hunmer/mira-core';
|
|
11
|
+
*
|
|
12
|
+
* // Create instances manually when needed
|
|
13
|
+
* const backend = new MiraBackend({ autoStart: false });
|
|
14
|
+
* // or use the static factory method to auto-start
|
|
15
|
+
* const backend = MiraBackend.createAndStart();
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.TagHandler = exports.PluginMessageHandler = exports.HandlerMessageHandler = exports.LibraryHandler = exports.FolderHandler = exports.FileHandler = exports.MiraBackend = exports.WebSocketRouter = exports.HttpRouter = exports.ServerPlugin = exports.MessageHandler = exports.LibraryStorage = exports.LibraryServerDataSQLite = exports.getLibrarysJson = exports.EventManager = exports.EventSubscription = exports.EventArgs = exports.ServerPluginManager = exports.MiraHttpServer = exports.MiraWebsocketServer = void 0;
|
|
19
|
+
var WebSocketServer_1 = require("./WebSocketServer");
|
|
20
|
+
Object.defineProperty(exports, "MiraWebsocketServer", { enumerable: true, get: function () { return WebSocketServer_1.MiraWebsocketServer; } });
|
|
21
|
+
var HttpServer_1 = require("./HttpServer");
|
|
22
|
+
Object.defineProperty(exports, "MiraHttpServer", { enumerable: true, get: function () { return HttpServer_1.MiraHttpServer; } });
|
|
23
|
+
var ServerPluginManager_1 = require("./ServerPluginManager");
|
|
24
|
+
Object.defineProperty(exports, "ServerPluginManager", { enumerable: true, get: function () { return ServerPluginManager_1.ServerPluginManager; } });
|
|
25
|
+
var event_manager_1 = require("./event-manager");
|
|
26
|
+
Object.defineProperty(exports, "EventArgs", { enumerable: true, get: function () { return event_manager_1.EventArgs; } });
|
|
27
|
+
Object.defineProperty(exports, "EventSubscription", { enumerable: true, get: function () { return event_manager_1.EventSubscription; } });
|
|
28
|
+
Object.defineProperty(exports, "EventManager", { enumerable: true, get: function () { return event_manager_1.EventManager; } });
|
|
29
|
+
var LibraryList_1 = require("./LibraryList");
|
|
30
|
+
Object.defineProperty(exports, "getLibrarysJson", { enumerable: true, get: function () { return LibraryList_1.getLibrarysJson; } });
|
|
31
|
+
var LibraryServerDataSQLite_1 = require("./LibraryServerDataSQLite");
|
|
32
|
+
Object.defineProperty(exports, "LibraryServerDataSQLite", { enumerable: true, get: function () { return LibraryServerDataSQLite_1.LibraryServerDataSQLite; } });
|
|
33
|
+
var LibraryStorage_1 = require("./LibraryStorage");
|
|
34
|
+
Object.defineProperty(exports, "LibraryStorage", { enumerable: true, get: function () { return LibraryStorage_1.LibraryStorage; } });
|
|
35
|
+
var MessageHandler_1 = require("./MessageHandler");
|
|
36
|
+
Object.defineProperty(exports, "MessageHandler", { enumerable: true, get: function () { return MessageHandler_1.MessageHandler; } });
|
|
37
|
+
var ServerPlugin_1 = require("./ServerPlugin");
|
|
38
|
+
Object.defineProperty(exports, "ServerPlugin", { enumerable: true, get: function () { return ServerPlugin_1.ServerPlugin; } });
|
|
39
|
+
var HttpRouter_1 = require("./HttpRouter");
|
|
40
|
+
Object.defineProperty(exports, "HttpRouter", { enumerable: true, get: function () { return HttpRouter_1.HttpRouter; } });
|
|
41
|
+
var WebSocketRouter_1 = require("./WebSocketRouter");
|
|
42
|
+
Object.defineProperty(exports, "WebSocketRouter", { enumerable: true, get: function () { return WebSocketRouter_1.WebSocketRouter; } });
|
|
43
|
+
var ServerExample_1 = require("./ServerExample");
|
|
44
|
+
Object.defineProperty(exports, "MiraBackend", { enumerable: true, get: function () { return ServerExample_1.MiraBackend; } });
|
|
45
|
+
// Re-export handlers
|
|
46
|
+
var FileHandler_1 = require("./handlers/FileHandler");
|
|
47
|
+
Object.defineProperty(exports, "FileHandler", { enumerable: true, get: function () { return FileHandler_1.FileHandler; } });
|
|
48
|
+
var FolderHandler_1 = require("./handlers/FolderHandler");
|
|
49
|
+
Object.defineProperty(exports, "FolderHandler", { enumerable: true, get: function () { return FolderHandler_1.FolderHandler; } });
|
|
50
|
+
var LibraryHandler_1 = require("./handlers/LibraryHandler");
|
|
51
|
+
Object.defineProperty(exports, "LibraryHandler", { enumerable: true, get: function () { return LibraryHandler_1.LibraryHandler; } });
|
|
52
|
+
var MessageHandler_2 = require("./handlers/MessageHandler");
|
|
53
|
+
Object.defineProperty(exports, "HandlerMessageHandler", { enumerable: true, get: function () { return MessageHandler_2.MessageHandler; } });
|
|
54
|
+
var PluginMessageHandler_1 = require("./handlers/PluginMessageHandler");
|
|
55
|
+
Object.defineProperty(exports, "PluginMessageHandler", { enumerable: true, get: function () { return PluginMessageHandler_1.PluginMessageHandler; } });
|
|
56
|
+
var TagHandler_1 = require("./handlers/TagHandler");
|
|
57
|
+
Object.defineProperty(exports, "TagHandler", { enumerable: true, get: function () { return TagHandler_1.TagHandler; } });
|
|
58
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAIH,qDAAwD;AAA/C,sHAAA,mBAAmB,OAAA;AAC5B,2CAA8C;AAArC,4GAAA,cAAc,OAAA;AACvB,6DAA0E;AAAjE,0HAAA,mBAAmB,OAAA;AAC5B,iDAA6E;AAApE,0GAAA,SAAS,OAAA;AAAE,kHAAA,iBAAiB,OAAA;AAAE,6GAAA,YAAY,OAAA;AACnD,6CAAgD;AAAvC,8GAAA,eAAe,OAAA;AACxB,qEAAoE;AAA3D,kIAAA,uBAAuB,OAAA;AAChC,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,mDAAkD;AAAzC,gHAAA,cAAc,OAAA;AACvB,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AACrB,2CAA0C;AAAjC,wGAAA,UAAU,OAAA;AACnB,qDAAsE;AAA7D,kHAAA,eAAe,OAAA;AACxB,iDAA8C;AAArC,4GAAA,WAAW,OAAA;AAEpB,qBAAqB;AACrB,sDAAqD;AAA5C,0GAAA,WAAW,OAAA;AACpB,0DAAyD;AAAhD,8GAAA,aAAa,OAAA;AACtB,4DAA2D;AAAlD,gHAAA,cAAc,OAAA;AACvB,4DAAoF;AAA3E,uHAAA,cAAc,OAAyB;AAChD,wEAAuE;AAA9D,4HAAA,oBAAoB,OAAA;AAC7B,oDAAmD;AAA1C,wGAAA,UAAU,OAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mira-app-core",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Core library for Mira TypeScript project - provides base functionality without auto-execution",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"prepublish": "npm run build"
|
|
10
|
+
},
|
|
11
|
+
"keywords": ["mira", "core", "library"],
|
|
12
|
+
"author": "hunmer",
|
|
13
|
+
"license": "ISC",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/express": "^5.0.3",
|
|
19
|
+
"@types/ws": "^8.18.1",
|
|
20
|
+
"typescript": "^5.3.3"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@types/multer": "^2.0.0",
|
|
24
|
+
"@types/sqlite3": "^3.1.11",
|
|
25
|
+
"axios": "^1.11.0",
|
|
26
|
+
"express": "^5.1.0",
|
|
27
|
+
"multer": "^2.0.2",
|
|
28
|
+
"queue": "^7.0.0",
|
|
29
|
+
"sqlite3": "^5.1.7",
|
|
30
|
+
"ws": "^8.18.3"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
import express, { Router, Request, Response, Handler } from 'express';
|
|
2
|
+
import multer from 'multer';
|
|
3
|
+
import { LibraryServerDataSQLite } from './LibraryServerDataSQLite';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import fs from 'fs';
|
|
6
|
+
import { MiraBackend } from './ServerExample';
|
|
7
|
+
|
|
8
|
+
// 配置multer文件上传
|
|
9
|
+
const storage = multer.diskStorage({
|
|
10
|
+
destination: (req, file, cb) => {
|
|
11
|
+
const tempDir = path.join(__dirname, '../../temp');
|
|
12
|
+
if (!fs.existsSync(tempDir)) {
|
|
13
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
cb(null, tempDir);
|
|
16
|
+
},
|
|
17
|
+
filename: (req, file, cb) => {
|
|
18
|
+
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
|
|
19
|
+
cb(null, uniqueSuffix + path.extname(file.originalname));
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const upload = multer({
|
|
24
|
+
storage: storage,
|
|
25
|
+
// limits: {
|
|
26
|
+
// fileSize: 100 * 1024 * 1024 // 限制100MB
|
|
27
|
+
// }
|
|
28
|
+
});
|
|
29
|
+
export class HttpRouter {
|
|
30
|
+
private router: Router;
|
|
31
|
+
private registerdRounters: Map<string, Handler> = new Map<string, Handler>();
|
|
32
|
+
private libraryServices: LibraryServerDataSQLite[] = [];
|
|
33
|
+
backend: MiraBackend;
|
|
34
|
+
|
|
35
|
+
constructor(bakend: MiraBackend) {
|
|
36
|
+
this.backend = bakend;
|
|
37
|
+
this.router = express.Router();
|
|
38
|
+
this.setupRoutes();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
registerRounter(path: string, method: string, router: Handler) {
|
|
42
|
+
if (this.registerdRounters.has(path)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
this.registerdRounters.set(path, router);
|
|
46
|
+
console.log('register rounter', path, method);
|
|
47
|
+
switch (method) {
|
|
48
|
+
case 'post':
|
|
49
|
+
this.router.post(path, router);
|
|
50
|
+
break;
|
|
51
|
+
case 'get':
|
|
52
|
+
this.router.get(path, router);
|
|
53
|
+
break;
|
|
54
|
+
default:
|
|
55
|
+
throw new Error('不支持的方法');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
unregisterRounter(path: string) {
|
|
60
|
+
this.router.unlink(path);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
private setupRoutes(): void {
|
|
64
|
+
this.router.post('/libraries/:libraryId/connect', async (req: Request, res: Response) => {
|
|
65
|
+
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
this.router.get('/libraries/:libraryId/status', (req: Request, res: Response) => {
|
|
69
|
+
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
// 上传文件
|
|
74
|
+
this.router.post('/libraries/upload', upload.array('files'), async (req: Request, res) => {
|
|
75
|
+
const { libraryId, sourcePath } = req.body; // sourcePath是用户的本地文件位置,用来验证是否上传成功
|
|
76
|
+
const clientId = req.body.clientId || null;
|
|
77
|
+
const fields = req.body.fields ? JSON.parse(req.body.fields) : null;
|
|
78
|
+
const payload = req.body.payload ? JSON.parse(req.body.payload) : null;
|
|
79
|
+
const library = this.backend.libraries.get(libraryId);
|
|
80
|
+
if (!library) return res.status(404).send('Library not found');
|
|
81
|
+
|
|
82
|
+
// 解析上传的文件
|
|
83
|
+
const files = req.files as Express.Multer.File[];
|
|
84
|
+
if (!files || !files.length) return res.status(400).send('No files uploaded.');
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
const results = [];
|
|
88
|
+
for (const file of files) {
|
|
89
|
+
try {
|
|
90
|
+
// 确保临时目录存在
|
|
91
|
+
const tempDir = path.join(__dirname, '../../temp');
|
|
92
|
+
if (!fs.existsSync(tempDir)) {
|
|
93
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// 生成唯一文件名并保存文件
|
|
97
|
+
const originalName = Buffer.from(file.originalname, 'latin1').toString('utf8');
|
|
98
|
+
const tempFilePath = path.join(tempDir, `${Date.now()}-${originalName}`);
|
|
99
|
+
|
|
100
|
+
// 确保有有效的文件数据
|
|
101
|
+
if (file.buffer) {
|
|
102
|
+
await fs.promises.writeFile(tempFilePath, file.buffer);
|
|
103
|
+
} else if (file.path) {
|
|
104
|
+
// 如果使用diskStorage,文件已保存到指定路径
|
|
105
|
+
await fs.promises.copyFile(file.path, tempFilePath);
|
|
106
|
+
} else {
|
|
107
|
+
throw new Error('No valid file data available');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
const {tags, folder_id} = payload.data || {}
|
|
111
|
+
const fileData = {
|
|
112
|
+
name: req.body.name || originalName,
|
|
113
|
+
tags: JSON.stringify(tags || []),
|
|
114
|
+
folder_id: folder_id || null,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const result = await library.createFileFromPath(tempFilePath, fileData, { importType: 'move' }); // 使用move上传完成后自动删除临时文件
|
|
118
|
+
results.push({
|
|
119
|
+
success: true,
|
|
120
|
+
file: tempFilePath,
|
|
121
|
+
result
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
// 发布公告
|
|
125
|
+
this.backend.webSocketServer.broadcastPluginEvent('file::created', {
|
|
126
|
+
message: {
|
|
127
|
+
type: 'file',
|
|
128
|
+
action: 'create',
|
|
129
|
+
fields, payload
|
|
130
|
+
}, result, libraryId
|
|
131
|
+
});
|
|
132
|
+
if (clientId) {
|
|
133
|
+
const ws = this.backend.webSocketServer.getWsClientById(libraryId, clientId);
|
|
134
|
+
ws && this.backend.webSocketServer.sendToWebsocket(ws, { eventName: 'file::uploaded', data: { path: sourcePath } });
|
|
135
|
+
this.backend.webSocketServer.broadcastLibraryEvent(libraryId, 'file::created', {...result, libraryId});
|
|
136
|
+
}
|
|
137
|
+
} catch (error) {
|
|
138
|
+
results.push({
|
|
139
|
+
success: false,
|
|
140
|
+
file: file.path,
|
|
141
|
+
error: error instanceof Error ? error.message : String(error)
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
res.send({ results });
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error('Error uploading files:', error);
|
|
148
|
+
res.status(500).send('Internal server error while processing the upload.');
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// 添加文件流路由
|
|
153
|
+
this.router.get('/thumb/:libraryId/:id', async (req, res) => {
|
|
154
|
+
try {
|
|
155
|
+
const ret = await this.parseLibraryItem(req, res);
|
|
156
|
+
if (ret) {
|
|
157
|
+
const thumbPath = await ret.library.getItemThumbPath(ret.item, { isNetworkImage: false });
|
|
158
|
+
if (!fs.existsSync(thumbPath)) return res.status(404).send('Thumbnail not found');
|
|
159
|
+
|
|
160
|
+
res.setHeader('Content-Type', 'image/png');
|
|
161
|
+
fs.createReadStream(thumbPath).pipe(res);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
} catch (err) {
|
|
165
|
+
console.error('Error serving thumbnail:', err);
|
|
166
|
+
res.status(500).send('Internal server error');
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
this.router.get('/file/:libraryId/:id', async (req, res) => {
|
|
172
|
+
const ret = await this.parseLibraryItem(req, res);
|
|
173
|
+
if (ret) {
|
|
174
|
+
const filePath = await ret.library.getItemFilePath(ret.item);
|
|
175
|
+
if (!filePath || !fs.existsSync(filePath)) {
|
|
176
|
+
return res.status(404).send('File not found');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const fileExt = path.extname(filePath).toLowerCase();
|
|
180
|
+
const contentType = this.getContentType(fileExt);
|
|
181
|
+
res.setHeader('Content-Type', contentType);
|
|
182
|
+
fs.createReadStream(filePath).pipe(res);
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
private async parseLibraryItem(req: express.Request, res: express.Response): Promise<{ library: any, item: any } | void> {
|
|
189
|
+
const { libraryId, id } = req.params;
|
|
190
|
+
const library = this.backend.libraries.get(libraryId);
|
|
191
|
+
if (!library) {
|
|
192
|
+
res.status(404).send('Library not found');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const item = await library.getFile(parseInt(id));
|
|
197
|
+
if (!item) {
|
|
198
|
+
res.status(404).send('Item not found');
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
return { library, item };
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
private getContentType(ext: string): string {
|
|
205
|
+
const mimeTypes: Record<string, string> = {
|
|
206
|
+
'.png': 'image/png',
|
|
207
|
+
'.jpg': 'image/jpeg',
|
|
208
|
+
'.jpeg': 'image/jpeg',
|
|
209
|
+
'.gif': 'image/gif',
|
|
210
|
+
'.pdf': 'application/pdf',
|
|
211
|
+
'.txt': 'text/plain',
|
|
212
|
+
'.html': 'text/html',
|
|
213
|
+
'.json': 'application/json',
|
|
214
|
+
'.mp4': 'video/mp4',
|
|
215
|
+
'.mp3': 'audio/mpeg',
|
|
216
|
+
'.zip': 'application/zip',
|
|
217
|
+
'.doc': 'application/msword',
|
|
218
|
+
'.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
219
|
+
'.xls': 'application/vnd.ms-excel',
|
|
220
|
+
'.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
221
|
+
'.ppt': 'application/vnd.ms-powerpoint',
|
|
222
|
+
'.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation'
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
return mimeTypes[ext] || 'application/octet-stream';
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
getRouter(): Router {
|
|
229
|
+
return this.router;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
async close(): Promise<void> {
|
|
233
|
+
await Promise.all(this.libraryServices.map(service => service.close()));
|
|
234
|
+
this.libraryServices = [];
|
|
235
|
+
}
|
|
236
|
+
}
|