@simplysm/service-server 13.0.76 → 13.0.77
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/README.md +3 -3
- package/dist/core/define-service.js +2 -2
- package/dist/core/define-service.js.map +1 -1
- package/dist/core/service-executor.d.ts +1 -1
- package/dist/core/service-executor.d.ts.map +1 -1
- package/dist/core/service-executor.js +2 -2
- package/dist/core/service-executor.js.map +1 -1
- package/dist/protocol/protocol-wrapper.d.ts +2 -2
- package/dist/protocol/protocol-wrapper.d.ts.map +1 -1
- package/dist/protocol/protocol-wrapper.js +2 -2
- package/dist/protocol/protocol-wrapper.js.map +1 -1
- package/dist/service-server.d.ts +1 -1
- package/dist/service-server.d.ts.map +1 -1
- package/dist/service-server.js +9 -9
- package/dist/service-server.js.map +1 -1
- package/dist/services/auto-update-service.js +4 -4
- package/dist/services/auto-update-service.js.map +1 -1
- package/dist/services/smtp-client-service.js.map +1 -1
- package/dist/transport/http/http-request-handler.js +2 -2
- package/dist/transport/http/http-request-handler.js.map +1 -1
- package/dist/transport/http/static-file-handler.js +3 -3
- package/dist/transport/http/static-file-handler.js.map +1 -1
- package/dist/transport/http/upload-handler.js +5 -5
- package/dist/transport/http/upload-handler.js.map +1 -1
- package/dist/transport/socket/service-socket.d.ts +2 -2
- package/dist/transport/socket/service-socket.d.ts.map +1 -1
- package/dist/transport/socket/service-socket.js +4 -4
- package/dist/transport/socket/service-socket.js.map +1 -1
- package/dist/transport/socket/websocket-handler.d.ts +2 -2
- package/dist/transport/socket/websocket-handler.d.ts.map +1 -1
- package/dist/transport/socket/websocket-handler.js +5 -5
- package/dist/transport/socket/websocket-handler.js.map +1 -1
- package/dist/utils/config-manager.js +5 -5
- package/dist/utils/config-manager.js.map +1 -1
- package/dist/workers/service-protocol.worker.d.ts +1 -1
- package/package.json +6 -6
- package/src/core/define-service.ts +2 -2
- package/src/core/service-executor.ts +1 -1
- package/src/protocol/protocol-wrapper.ts +2 -2
- package/src/service-server.ts +9 -9
- package/src/services/auto-update-service.ts +4 -4
- package/src/services/smtp-client-service.ts +2 -2
- package/src/transport/http/http-request-handler.ts +2 -2
- package/src/transport/http/static-file-handler.ts +3 -3
- package/src/transport/http/upload-handler.ts +5 -5
- package/src/transport/socket/service-socket.ts +6 -6
- package/src/transport/socket/websocket-handler.ts +7 -7
- package/src/utils/config-manager.ts +5 -5
- package/tests/service-executor.spec.ts +9 -9
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ await server.listen();
|
|
|
49
49
|
| `ServiceMethods<TDefinition>` | Extracts method map type from a `ServiceDefinition` |
|
|
50
50
|
| `WebSocketHandler` | Manages all active WebSocket connections |
|
|
51
51
|
| `ServiceSocket` | Represents a single active WebSocket connection |
|
|
52
|
-
| `
|
|
52
|
+
| `ServerProtocolWrapper` | Encode/decode service messages with optional worker offload |
|
|
53
53
|
| `OrmServiceType` | Method map type for `OrmService` |
|
|
54
54
|
| `AutoUpdateServiceType` | Method map type for `AutoUpdateService` |
|
|
55
55
|
| `SmtpClientServiceType` | Method map type for `SmtpClientService` |
|
|
@@ -57,6 +57,6 @@ await server.listen();
|
|
|
57
57
|
## Detailed Documentation
|
|
58
58
|
|
|
59
59
|
- [docs/auth.md](docs/auth.md) — `AuthTokenPayload`, `signJwt`, `verifyJwt`, `decodeJwt`
|
|
60
|
-
- [docs/services.md](docs/services.md) — `defineService`, `auth`, `ServiceContext`, `
|
|
61
|
-
- [docs/transport.md](docs/transport.md) — `WebSocketHandler`, `ServiceSocket`, `handleHttpRequest`, `handleUpload`, `handleStaticFile`, `
|
|
60
|
+
- [docs/services.md](docs/services.md) — `defineService`, `auth`, `ServiceContext`, `executeServiceMethod`, `OrmService`, `AutoUpdateService`, `SmtpClientService`
|
|
61
|
+
- [docs/transport.md](docs/transport.md) — `WebSocketHandler`, `ServiceSocket`, `handleHttpRequest`, `handleUpload`, `handleStaticFile`, `ServerProtocolWrapper`, legacy handler
|
|
62
62
|
- [docs/server.md](docs/server.md) — `ServiceServerOptions`, `ServiceServer`, `createServiceServer`, `getConfig`
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { obj } from "@simplysm/core-common";
|
|
2
2
|
import { getConfig } from "../utils/config-manager.js";
|
|
3
3
|
import path from "path";
|
|
4
4
|
function createServiceContext(server, socket, http, legacy) {
|
|
@@ -34,7 +34,7 @@ function createServiceContext(server, socket, http, legacy) {
|
|
|
34
34
|
const clientFilePath = path.resolve(targetPath, ".config.json");
|
|
35
35
|
const clientConfig = await getConfig(clientFilePath);
|
|
36
36
|
if (clientConfig != null) {
|
|
37
|
-
configParent =
|
|
37
|
+
configParent = obj.merge(configParent, clientConfig);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
const config = configParent[section];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/core/define-service.ts"],
|
|
4
|
-
"mappings": "AAGA,SAAS,
|
|
4
|
+
"mappings": "AAGA,SAAS,WAAW;AACpB,SAAS,iBAAiB;AAC1B,OAAO,UAAU;AAuBV,SAAS,qBACd,QACA,QACA,MACA,QAC2B;AAC3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IAEA,IAAI,WAAkC;AACpC,aAAQ,QAAQ,kBAAkB,QAAQ,MAAM,kBAAkB;AAAA,IAGpE;AAAA,IAEA,IAAI,aAAiC;AACnC,YAAM,OAAO,QAAQ,cAAc,MAAM,cAAc,QAAQ;AAC/D,UAAI,QAAQ,KAAM,QAAO;AAEzB,UAAI,SAAS,MAAM,KAAK,SAAS,IAAI,KAAK,KAAK,SAAS,GAAG,KAAK,KAAK,SAAS,IAAI,GAAG;AACnF,cAAM,IAAI,MAAM,wBAAwB,IAAI,EAAE;AAAA,MAChD;AAEA,aAAO;AAAA,IACT;AAAA,IAEA,IAAI,aAAiC;AACnC,YAAM,OAAO,KAAK;AAClB,aAAO,QAAQ,OAAO,SAAY,KAAK,QAAQ,OAAO,QAAQ,UAAU,OAAO,IAAI;AAAA,IACrF;AAAA,IAEA,MAAM,UAAa,SAA6B;AAC9C,UAAI,eAA8C,CAAC;AAEnD,YAAM,eAAe,KAAK,QAAQ,OAAO,QAAQ,UAAU,cAAc;AACzE,YAAM,aAAa,MAAM,UAA6B,YAAY;AAClE,UAAI,cAAc,MAAM;AACtB,uBAAe;AAAA,MACjB;AAEA,YAAM,aAAa,KAAK;AACxB,UAAI,cAAc,MAAM;AACtB,cAAM,iBAAiB,KAAK,QAAQ,YAAY,cAAc;AAC9D,cAAM,eAAe,MAAM,UAA6B,cAAc;AACtE,YAAI,gBAAgB,MAAM;AACxB,yBAAe,IAAI,MAAM,cAAc,YAAY;AAAA,QACrD;AAAA,MACF;AAEA,YAAM,SAAS,aAAa,OAAO;AACnC,UAAI,UAAU,KAAM,OAAM,IAAI,MAAM,oCAAoC,OAAO,EAAE;AACjF,aAAO;AAAA,IACT;AAAA,EACF;AACF;AAIA,MAAM,mBAAmB,uBAAO,iBAAiB;AAG1C,SAAS,0BAA0B,IAAoC;AAC5E,SAAQ,GAA0C,gBAAgB;AACpE;AAeO,SAAS,KAAK,iBAAsC,SAA8B;AACvF,QAAM,cAAc,MAAM,QAAQ,eAAe,IAAI,kBAAkB,CAAC;AACxE,QAAM,KAAK,MAAM,QAAQ,eAAe,IAAI,UAAW;AAGvD,QAAM,UAAU,IAAI,SAAoB,GAAG,GAAG,IAAI;AAClD,EAAC,QAA+C,gBAAgB,IAAI;AAEpE,SAAO;AACT;AAyBO,SAAS,cACd,MACA,SAC6B;AAC7B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,iBAAiB,0BAA0B,OAAO;AAAA,EACpD;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ServiceServer } from "../service-server";
|
|
2
2
|
import type { ServiceSocket } from "../transport/socket/service-socket";
|
|
3
3
|
import type { AuthTokenPayload } from "../auth/auth-token-payload";
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function executeServiceMethod(server: ServiceServer, def: {
|
|
5
5
|
serviceName: string;
|
|
6
6
|
methodName: string;
|
|
7
7
|
params: unknown[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-executor.d.ts","sourceRoot":"","sources":["..\\..\\src\\core\\service-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,wBAAsB,
|
|
1
|
+
{"version":3,"file":"service-executor.d.ts","sourceRoot":"","sources":["..\\..\\src\\core\\service-executor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAGnE,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,IAAI,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAA;KAAE,CAAC;CACpE,GACA,OAAO,CAAC,OAAO,CAAC,CAoDlB"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createServiceContext, getServiceAuthPermissions } from "./define-service.js";
|
|
2
|
-
async function
|
|
2
|
+
async function executeServiceMethod(server, def) {
|
|
3
3
|
const serviceDef = server.options.services.find((item) => item.name === def.serviceName);
|
|
4
4
|
if (serviceDef == null) {
|
|
5
5
|
throw new Error(`Service [${def.serviceName}] not found.`);
|
|
@@ -35,6 +35,6 @@ async function runServiceMethod(server, def) {
|
|
|
35
35
|
return await method(...def.params);
|
|
36
36
|
}
|
|
37
37
|
export {
|
|
38
|
-
|
|
38
|
+
executeServiceMethod
|
|
39
39
|
};
|
|
40
40
|
//# sourceMappingURL=service-executor.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/core/service-executor.ts"],
|
|
4
|
-
"mappings": "AAGA,SAAS,sBAAsB,iCAAiC;AAEhE,eAAsB,
|
|
4
|
+
"mappings": "AAGA,SAAS,sBAAsB,iCAAiC;AAEhE,eAAsB,qBACpB,QACA,KAOkB;AAElB,QAAM,aAAa,OAAO,QAAQ,SAAS,KAAK,CAAC,SAAS,KAAK,SAAS,IAAI,WAAW;AAEvF,MAAI,cAAc,MAAM;AACtB,UAAM,IAAI,MAAM,YAAY,IAAI,WAAW,cAAc;AAAA,EAC3D;AAGA,QAAM,aAAa,IAAI,QAAQ,cAAc,IAAI,MAAM;AACvD,MAAI,cAAc,MAAM;AACtB,QAAI,WAAW,SAAS,IAAI,KAAK,WAAW,SAAS,GAAG,KAAK,WAAW,SAAS,IAAI,GAAG;AACtF,YAAM,IAAI,MAAM,mCAAmC,UAAU,EAAE;AAAA,IACjE;AAAA,EACF;AAGA,QAAM,MAAM,qBAAqB,QAAQ,IAAI,QAAQ,IAAI,IAAI;AAG7D,QAAM,UAAU,WAAW,QAAQ,GAAG;AAGtC,QAAM,SAAU,QAAoC,IAAI,UAAU;AAClE,MAAI,OAAO,WAAW,YAAY;AAChC,UAAM,IAAI,MAAM,WAAW,IAAI,WAAW,IAAI,IAAI,UAAU,cAAc;AAAA,EAC5E;AAGA,MAAI,OAAO,QAAQ,QAAQ,MAAM;AAE/B,UAAM,cAAc,0BAA0B,MAAM;AACpD,UAAM,gBAAgB,eAAe,WAAW;AAEhD,QAAI,iBAAiB,MAAM;AACzB,YAAM,mBAAmB,IAAI,QAAQ,oBAAoB,IAAI,MAAM;AAEnE,UAAI,oBAAoB,MAAM;AAC5B,cAAM,IAAI,MAAM,oBAAoB;AAAA,MACtC;AAEA,UAAI,cAAc,SAAS,GAAG;AAC5B,cAAM,UAAU,cAAc,KAAK,CAAC,SAAS,iBAAiB,MAAM,SAAS,IAAI,CAAC;AAClF,YAAI,CAAC,SAAS;AACZ,gBAAM,IAAI,MAAM,2BAA2B;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO,MAAM,OAAO,GAAG,IAAI,MAAM;AACnC;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -6,7 +6,7 @@ import type { ServiceMessageDecodeResult, ServiceMessage } from "@simplysm/servi
|
|
|
6
6
|
* Automatically offloads heavy message encoding/decoding to a worker thread
|
|
7
7
|
* while using main thread for lightweight operations.
|
|
8
8
|
*/
|
|
9
|
-
export interface
|
|
9
|
+
export interface ServerProtocolWrapper {
|
|
10
10
|
/**
|
|
11
11
|
* Encode message (auto worker delegation)
|
|
12
12
|
*/
|
|
@@ -29,5 +29,5 @@ export interface ProtocolWrapper {
|
|
|
29
29
|
* Automatically offloads heavy message encoding/decoding to a worker thread
|
|
30
30
|
* while using main thread for lightweight operations.
|
|
31
31
|
*/
|
|
32
|
-
export declare function
|
|
32
|
+
export declare function createServerProtocolWrapper(): ServerProtocolWrapper;
|
|
33
33
|
//# sourceMappingURL=protocol-wrapper.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protocol-wrapper.d.ts","sourceRoot":"","sources":["..\\..\\src\\protocol\\protocol-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI3F;;;;;GAKG;AACH,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"protocol-wrapper.d.ts","sourceRoot":"","sources":["..\\..\\src\\protocol\\protocol-wrapper.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAEnD,OAAO,KAAK,EAAE,0BAA0B,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAI3F;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC;QAAE,MAAM,EAAE,KAAK,EAAE,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAE/F;;OAEG;IACH,MAAM,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,0BAA0B,CAAC,cAAc,CAAC,CAAC,CAAC;IAE1E;;OAEG;IACH,OAAO,IAAI,IAAI,CAAC;CACjB;AAiBD;;;;;GAKG;AACH,wBAAgB,2BAA2B,IAAI,qBAAqB,CA8DnE"}
|
|
@@ -12,7 +12,7 @@ function getWorker() {
|
|
|
12
12
|
}
|
|
13
13
|
return sharedWorker;
|
|
14
14
|
}
|
|
15
|
-
function
|
|
15
|
+
function createServerProtocolWrapper() {
|
|
16
16
|
const protocol = createServiceProtocol();
|
|
17
17
|
const SIZE_THRESHOLD = 30 * 1024;
|
|
18
18
|
function shouldUseWorkerForEncode(msg) {
|
|
@@ -48,6 +48,6 @@ function createProtocolWrapper() {
|
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
export {
|
|
51
|
-
|
|
51
|
+
createServerProtocolWrapper
|
|
52
52
|
};
|
|
53
53
|
//# sourceMappingURL=protocol-wrapper.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/protocol/protocol-wrapper.ts"],
|
|
4
|
-
"mappings": "AACA,SAAS,cAAgC;AAEzC,SAAS,6BAA6B;AA2BtC,IAAI;AAEJ,SAAS,YAA6D;AACpE,MAAI,gBAAgB,MAAM;AACxB,mBAAe,OAAO;AAAA,MACpB,YAAY,QAAQ,oCAAoC;AAAA,MACxD;AAAA,QACE,gBAAgB,EAAE,wBAAwB,KAAK;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,
|
|
4
|
+
"mappings": "AACA,SAAS,cAAgC;AAEzC,SAAS,6BAA6B;AA2BtC,IAAI;AAEJ,SAAS,YAA6D;AACpE,MAAI,gBAAgB,MAAM;AACxB,mBAAe,OAAO;AAAA,MACpB,YAAY,QAAQ,oCAAoC;AAAA,MACxD;AAAA,QACE,gBAAgB,EAAE,wBAAwB,KAAK;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAQO,SAAS,8BAAqD;AAKnE,QAAM,WAAW,sBAAsB;AACvC,QAAM,iBAAiB,KAAK;AAS5B,WAAS,yBAAyB,KAA8B;AAC9D,QAAI,EAAE,UAAU,KAAM,QAAO;AAE7B,UAAM,OAAO,IAAI;AAGjB,QAAI,gBAAgB,YAAY;AAC9B,aAAO;AAAA,IACT;AAGA,QAAI,MAAM,QAAQ,IAAI,GAAG;AACvB,aAAO,KAAK,SAAS,KAAK,KAAK,KAAK,CAAC,SAAS,gBAAgB,UAAU;AAAA,IAC1E;AAEA,WAAO;AAAA,EACT;AAMA,SAAO;AAAA,IACL,MAAM,OACJ,MACA,SACiD;AACjD,UAAI,yBAAyB,OAAO,GAAG;AACrC,eAAO,UAAU,EAAE,OAAO,MAAM,OAAO;AAAA,MACzC,OAAO;AACL,eAAO,SAAS,OAAO,MAAM,OAAO;AAAA,MACtC;AAAA,IACF;AAAA,IAEA,MAAM,OAAO,OAAmE;AAC9E,YAAM,YAAY,MAAM;AACxB,UAAI,YAAY,gBAAgB;AAC9B,eAAO,UAAU,EAAE,OAAO,KAAK;AAAA,MACjC,OAAO;AACL,eAAO,SAAS,OAAO,KAAK;AAAA,MAC9B;AAAA,IACF;AAAA,IAEA,UAAgB;AACd,eAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
package/dist/service-server.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ export declare class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
|
|
|
16
16
|
close(): Promise<void>;
|
|
17
17
|
broadcastReload(clientName: string | undefined, changedFileSet: Set<string>): Promise<void>;
|
|
18
18
|
emitEvent<TInfo, TData>(eventDef: ServiceEventDef<TInfo, TData>, infoSelector: (item: TInfo) => boolean, data: TData): Promise<void>;
|
|
19
|
-
|
|
19
|
+
signAuthToken(payload: AuthTokenPayload<TAuthInfo>): Promise<string>;
|
|
20
20
|
verifyAuthToken(token: string): Promise<AuthTokenPayload<TAuthInfo>>;
|
|
21
21
|
private _registerGracefulShutdown;
|
|
22
22
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-server.d.ts","sourceRoot":"","sources":["..\\src\\service-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIhE,OAAO,
|
|
1
|
+
{"version":3,"file":"service-server.d.ts","sourceRoot":"","sources":["..\\src\\service-server.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAIhE,OAAO,EAAQ,YAAY,EAAO,MAAM,uBAAuB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAkB,MAAM,SAAS,CAAC;AAa/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAOnE,qBAAa,aAAa,CAAC,SAAS,GAAG,OAAO,CAAE,SAAQ,YAAY,CAAC;IACnE,KAAK,EAAE,IAAI,CAAC;IACZ,KAAK,EAAE,IAAI,CAAC;CACb,CAAC;IAOY,QAAQ,CAAC,OAAO,EAAE,oBAAoB;IANlD,MAAM,UAAS;IAEf,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4C;IAEvE,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAC;gBAEb,OAAO,EAAE,oBAAoB;IAiB5C,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IA4IvB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC;IAK3E,SAAS,CAAC,KAAK,EAAE,KAAK,EAC1B,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EACtC,IAAI,EAAE,KAAK;IAKP,aAAa,CAAC,OAAO,EAAE,gBAAgB,CAAC,SAAS,CAAC;IAOlD,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAO1E,OAAO,CAAC,yBAAyB;CAyBlC;AAED,wBAAgB,mBAAmB,CAAC,SAAS,GAAG,OAAO,EACrD,OAAO,EAAE,oBAAoB,GAC5B,aAAa,CAAC,SAAS,CAAC,CAE1B"}
|
package/dist/service-server.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { handleStaticFile } from "./transport/http/static-file-handler.js";
|
|
2
2
|
import { handleHttpRequest } from "./transport/http/http-request-handler.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { executeServiceMethod } from "./core/service-executor.js";
|
|
4
|
+
import { json, EventEmitter, env } from "@simplysm/core-common";
|
|
5
5
|
import fastify from "fastify";
|
|
6
6
|
import fastifyWebsocket from "@fastify/websocket";
|
|
7
7
|
import fastifyStatic from "@fastify/static";
|
|
@@ -24,7 +24,7 @@ class ServiceServer extends EventEmitter {
|
|
|
24
24
|
const httpsConf = options.ssl ? { pfx: Buffer.from(options.ssl.pfxBytes), passphrase: options.ssl.passphrase } : null;
|
|
25
25
|
this.fastify = fastify({ https: httpsConf });
|
|
26
26
|
this._wsHandler = createWebSocketHandler(
|
|
27
|
-
(def) =>
|
|
27
|
+
(def) => executeServiceMethod(this, def),
|
|
28
28
|
options.auth?.jwtSecret
|
|
29
29
|
);
|
|
30
30
|
}
|
|
@@ -69,8 +69,8 @@ class ServiceServer extends EventEmitter {
|
|
|
69
69
|
{ parseAs: "string" },
|
|
70
70
|
(req, body, done) => {
|
|
71
71
|
try {
|
|
72
|
-
const
|
|
73
|
-
done(null,
|
|
72
|
+
const parsed = json.parse(body);
|
|
73
|
+
done(null, parsed);
|
|
74
74
|
} catch (err) {
|
|
75
75
|
const error = err;
|
|
76
76
|
error.statusCode = 400;
|
|
@@ -78,13 +78,13 @@ class ServiceServer extends EventEmitter {
|
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
);
|
|
81
|
-
this.fastify.setSerializerCompiler(() => (data) =>
|
|
81
|
+
this.fastify.setSerializerCompiler(() => (data) => json.stringify(data));
|
|
82
82
|
this.fastify.all("/api/:service/:method", async (req, reply) => {
|
|
83
83
|
await handleHttpRequest(
|
|
84
84
|
req,
|
|
85
85
|
reply,
|
|
86
86
|
this.options.auth?.jwtSecret,
|
|
87
|
-
(def) =>
|
|
87
|
+
(def) => executeServiceMethod(this, def)
|
|
88
88
|
);
|
|
89
89
|
});
|
|
90
90
|
this.fastify.all("/upload", async (req, reply) => {
|
|
@@ -143,9 +143,9 @@ class ServiceServer extends EventEmitter {
|
|
|
143
143
|
await this._wsHandler.broadcastReload(clientName, changedFileSet);
|
|
144
144
|
}
|
|
145
145
|
async emitEvent(eventDef, infoSelector, data) {
|
|
146
|
-
await this._wsHandler.
|
|
146
|
+
await this._wsHandler.emit(eventDef, infoSelector, data);
|
|
147
147
|
}
|
|
148
|
-
async
|
|
148
|
+
async signAuthToken(payload) {
|
|
149
149
|
const jwtSecret = this.options.auth?.jwtSecret;
|
|
150
150
|
if (jwtSecret == null) throw new Error("JWT Secret is not defined.");
|
|
151
151
|
return signJwt(jwtSecret, payload);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/service-server.ts"],
|
|
4
|
-
"mappings": "AACA,SAAS,wBAAwB;AACjC,SAAS,yBAAyB;AAClC,SAAS,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import semver from "semver";
|
|
3
|
-
import {
|
|
3
|
+
import { fsx, pathx } from "@simplysm/core-node";
|
|
4
4
|
import { defineService } from "../core/define-service.js";
|
|
5
5
|
const AutoUpdateService = defineService("AutoUpdate", (ctx) => ({
|
|
6
6
|
async getLastVersion(platform) {
|
|
7
7
|
const clientPath = ctx.clientPath;
|
|
8
8
|
if (clientPath == null) throw new Error("Client path not found.");
|
|
9
|
-
if (!await
|
|
10
|
-
const updates = await
|
|
9
|
+
if (!await fsx.exists(path.resolve(clientPath, platform, "updates"))) return void 0;
|
|
10
|
+
const updates = await fsx.readdir(path.resolve(clientPath, platform, "updates"));
|
|
11
11
|
const versions = updates.map((item) => ({
|
|
12
12
|
fileName: item,
|
|
13
13
|
version: path.basename(item, path.extname(item)),
|
|
@@ -26,7 +26,7 @@ const AutoUpdateService = defineService("AutoUpdate", (ctx) => ({
|
|
|
26
26
|
if (version == null) return void 0;
|
|
27
27
|
const versionItem = versions.find((item) => item.version === version);
|
|
28
28
|
if (versionItem == null) return void 0;
|
|
29
|
-
const downloadPath = "/" +
|
|
29
|
+
const downloadPath = "/" + pathx.posix(ctx.clientName ?? "", platform, "updates", versionItem.fileName);
|
|
30
30
|
return {
|
|
31
31
|
version: version.toString(),
|
|
32
32
|
downloadPath
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/services/auto-update-service.ts"],
|
|
4
|
-
"mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,YAAY;AACnB,SAAS,
|
|
4
|
+
"mappings": "AAAA,OAAO,UAAU;AACjB,OAAO,YAAY;AACnB,SAAS,KAAK,aAAa;AAC3B,SAAS,qBAA0C;AAE5C,MAAM,oBAAoB,cAAc,cAAc,CAAC,SAAS;AAAA,EACrE,MAAM,eAAe,UAMnB;AACA,UAAM,aAAa,IAAI;AACvB,QAAI,cAAc,KAAM,OAAM,IAAI,MAAM,wBAAwB;AAEhE,QAAI,CAAE,MAAM,IAAI,OAAO,KAAK,QAAQ,YAAY,UAAU,SAAS,CAAC,EAAI,QAAO;AAE/E,UAAM,UAAU,MAAM,IAAI,QAAQ,KAAK,QAAQ,YAAY,UAAU,SAAS,CAAC;AAC/E,UAAM,WAAW,QACd,IAAI,CAAC,UAAU;AAAA,MACd,UAAU;AAAA,MACV,SAAS,KAAK,SAAS,MAAM,KAAK,QAAQ,IAAI,CAAC;AAAA,MAC/C,SAAS,KAAK,QAAQ,IAAI;AAAA,IAC5B,EAAE,EACD,OAAO,CAAC,SAAS;AAChB,UAAI,aAAa,WAAW;AAC1B,eAAO,KAAK,YAAY,UAAU,YAAY,KAAK,KAAK,OAAO;AAAA,MACjE,OAAO;AACL,eAAO,KAAK,YAAY,UAAU,YAAY,KAAK,KAAK,OAAO;AAAA,MACjE;AAAA,IACF,CAAC;AAEH,UAAM,UAAU,OAAO;AAAA,MACrB,SAAS,IAAI,CAAC,SAAS,KAAK,OAAO;AAAA,MACnC;AAAA,IACF;AAEA,QAAI,WAAW,KAAM,QAAO;AAE5B,UAAM,cAAc,SAAS,KAAK,CAAC,SAAS,KAAK,YAAY,OAAO;AACpE,QAAI,eAAe,KAAM,QAAO;AAEhC,UAAM,eACJ,MAAM,MAAM,MAAM,IAAI,cAAc,IAAI,UAAU,WAAW,YAAY,QAAQ;AAEnF,WAAO;AAAA,MACL,SAAS,QAAQ,SAAS;AAAA,MAC1B;AAAA,IACF;AAAA,EACF;AACF,EAAE;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/services/smtp-client-service.ts"],
|
|
4
|
-
"mappings": "AAAA,OAAO,gBAAgB;AACvB,SAAS,qBAA0C;AAO5C,MAAM,oBAAoB,cAAc,cAAc,CAAC,SAAS;AAAA,EACrE,MAAM,KAAK,SAAgD;AACzD,WAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9C,YAAM,YAAY,WAAW,gBAAgB;AAAA,QAC3C,MAAM,QAAQ;AAAA,QACd,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,MACE,QAAQ,QAAQ,OACZ;AAAA,UACE,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ;AAAA,QAChB,IACA;AAAA,QACN,KAAK;AAAA,UACH,oBAAoB;AAAA,QACtB;AAAA,MACF,CAAC;AAED,gBAAU,SAAS,SAAuC,CAAC,KAAK,SAAS;AACvE,YAAI,KAAK;AACP,iBAAO,GAAG;AACV;AAAA,QACF;AAEA,gBAAQ,KAAK,SAAS;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,YAAoB,SAAyD;AAC9F,UAAM,UACJ,MAAM,IAAI,
|
|
4
|
+
"mappings": "AAAA,OAAO,gBAAgB;AACvB,SAAS,qBAA0C;AAO5C,MAAM,oBAAoB,cAAc,cAAc,CAAC,SAAS;AAAA,EACrE,MAAM,KAAK,SAAgD;AACzD,WAAO,IAAI,QAAgB,CAAC,SAAS,WAAW;AAC9C,YAAM,YAAY,WAAW,gBAAgB;AAAA,QAC3C,MAAM,QAAQ;AAAA,QACd,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ;AAAA,QAChB,MACE,QAAQ,QAAQ,OACZ;AAAA,UACE,MAAM,QAAQ;AAAA,UACd,MAAM,QAAQ;AAAA,QAChB,IACA;AAAA,QACN,KAAK;AAAA,UACH,oBAAoB;AAAA,QACtB;AAAA,MACF,CAAC;AAED,gBAAU,SAAS,SAAuC,CAAC,KAAK,SAAS;AACvE,YAAI,KAAK;AACP,iBAAO,GAAG;AACV;AAAA,QACF;AAEA,gBAAQ,KAAK,SAAS;AAAA,MACxB,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,aAAa,YAAoB,SAAyD;AAC9F,UAAM,UACJ,MAAM,IAAI,UAAgE,MAAM,GAChF,UAAU;AACZ,QAAI,UAAU,MAAM;AAClB,YAAM,IAAI,MAAM,0BAA0B,UAAU,EAAE;AAAA,IACxD;AAEA,WAAO,KAAK,KAAK;AAAA,MACf,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,MAAM,OAAO;AAAA,MACb,QAAQ,OAAO;AAAA,MACf,MAAM,IAAI,OAAO,UAAU,MAAM,OAAO,eAAe,OAAO,IAAI;AAAA,MAClE,GAAG;AAAA,IACL,CAAC;AAAA,EACH;AACF,EAAE;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { json } from "@simplysm/core-common";
|
|
2
2
|
import { verifyJwt } from "../../auth/jwt-manager.js";
|
|
3
3
|
async function handleHttpRequest(req, reply, jwtSecret, runMethod) {
|
|
4
4
|
const { service, method } = req.params;
|
|
@@ -25,7 +25,7 @@ async function handleHttpRequest(req, reply, jwtSecret, runMethod) {
|
|
|
25
25
|
if (typeof query.json !== "string") {
|
|
26
26
|
throw new Error("JSON query parameter required");
|
|
27
27
|
}
|
|
28
|
-
params =
|
|
28
|
+
params = json.parse(query.json);
|
|
29
29
|
} else if (req.method === "POST") {
|
|
30
30
|
if (!Array.isArray(req.body)) {
|
|
31
31
|
reply.status(400).send({
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/transport/http/http-request-handler.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,
|
|
4
|
+
"mappings": "AAAA,SAAS,YAAY;AAErB,SAAS,iBAAiB;AAG1B,eAAsB,kBACpB,KACA,OACA,WACA,WAMe;AACf,QAAM,EAAE,SAAS,OAAO,IAAI,IAAI;AAGhC,QAAM,aAAa,IAAI,QAAQ,kBAAkB;AACjD,MAAI,cAAc,KAAM,OAAM,IAAI,MAAM,+BAA+B;AAGvE,MAAI;AACJ,MAAI;AACF,UAAM,aAAa,IAAI,QAAQ;AAC/B,QAAI,cAAc,MAAM;AACtB,UAAI,aAAa,KAAM,OAAM,IAAI,MAAM,4BAA4B;AAEnE,YAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,CAAC;AACrC,yBAAmB,MAAM,UAAqB,WAAW,KAAK;AAAA,IAChE;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,OAAO,GAAG,EAAE,KAAK;AAAA,MACrB,OAAO;AAAA,MACP,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IAC1D,CAAC;AACD;AAAA,EACF;AAGA,MAAI;AACJ,MAAI,IAAI,WAAW,OAAO;AACxB,UAAM,QAAQ,IAAI;AAClB,QAAI,OAAO,MAAM,SAAS,UAAU;AAClC,YAAM,IAAI,MAAM,+BAA+B;AAAA,IACjD;AACA,aAAS,KAAK,MAAM,MAAM,IAAI;AAAA,EAChC,WAAW,IAAI,WAAW,QAAQ;AAChC,QAAI,CAAC,MAAM,QAAQ,IAAI,IAAI,GAAG;AAC5B,YAAM,OAAO,GAAG,EAAE,KAAK;AAAA,QACrB,OAAO;AAAA,QACP,SAAS;AAAA,MACX,CAAC;AACD;AAAA,IACF;AAEA,aAAS,IAAI;AAAA,EACf;AAGA,MAAI,UAAU,MAAM;AAClB,UAAM,gBAAgB,MAAM,UAAU;AAAA,MACpC,aAAa;AAAA,MACb,YAAY;AAAA,MACZ;AAAA,MACA,MAAM,EAAE,YAAY,iBAAiB;AAAA,IACvC,CAAC;AAED,UAAM,KAAK,aAAa;AAAA,EAC1B;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import {
|
|
2
|
+
import { fsx, pathx } from "@simplysm/core-node";
|
|
3
3
|
import consola from "consola";
|
|
4
4
|
const logger = consola.withTag("service-server:StaticFileHandler");
|
|
5
5
|
async function handleStaticFile(req, reply, rootPath, urlPath) {
|
|
6
6
|
let targetFilePath = path.resolve(rootPath, "www", urlPath);
|
|
7
7
|
const allowedRootPath = path.resolve(rootPath, "www");
|
|
8
|
-
if (targetFilePath !== allowedRootPath && !
|
|
8
|
+
if (targetFilePath !== allowedRootPath && !pathx.isChildPath(targetFilePath, allowedRootPath)) {
|
|
9
9
|
throw new Error("Access denied");
|
|
10
10
|
}
|
|
11
|
-
if (await
|
|
11
|
+
if (await fsx.exists(targetFilePath) && (await fsx.stat(targetFilePath)).isDirectory()) {
|
|
12
12
|
if (!urlPath.endsWith("/")) {
|
|
13
13
|
const urlObj = new URL(req.raw.url, "http://localhost");
|
|
14
14
|
reply.redirect(urlObj.pathname + "/" + urlObj.search);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/transport/http/static-file-handler.ts"],
|
|
4
|
-
"mappings": "AAAA,OAAO,UAAU;AACjB,SAAS,
|
|
4
|
+
"mappings": "AAAA,OAAO,UAAU;AACjB,SAAS,KAAK,aAAa;AAE3B,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,kCAAkC;AAEjE,eAAsB,iBACpB,KACA,OACA,UACA,SACe;AACf,MAAI,iBAAiB,KAAK,QAAQ,UAAU,OAAO,OAAO;AAC1D,QAAM,kBAAkB,KAAK,QAAQ,UAAU,KAAK;AAGpD,MAAI,mBAAmB,mBAAmB,CAAC,MAAM,YAAY,gBAAgB,eAAe,GAAG;AAC7F,UAAM,IAAI,MAAM,eAAe;AAAA,EACjC;AAGA,MAAK,MAAM,IAAI,OAAO,cAAc,MAAO,MAAM,IAAI,KAAK,cAAc,GAAG,YAAY,GAAG;AACxF,QAAI,CAAC,QAAQ,SAAS,GAAG,GAAG;AAC1B,YAAM,SAAS,IAAI,IAAI,IAAI,IAAI,KAAM,kBAAkB;AACvD,YAAM,SAAS,OAAO,WAAW,MAAM,OAAO,MAAM;AACpD;AAAA,IACF;AACA,qBAAiB,KAAK,QAAQ,gBAAgB,YAAY;AAAA,EAC5D;AAGA,MAAI,KAAK,SAAS,cAAc,EAAE,WAAW,GAAG,GAAG;AACjD,UAAM,eAAe;AACrB,sBAAkB,OAAO,KAAK,YAAY;AAC1C,WAAO,KAAK,SAAS,YAAY,KAAK,cAAc,GAAG;AACvD;AAAA,EACF;AAGA,QAAM,WAAW,KAAK,SAAS,cAAc;AAC7C,QAAM,YAAY,KAAK,QAAQ,cAAc;AAE7C,MAAI;AACF,WAAO,MAAM,MAAM,SAAS,UAAU,SAAS;AAAA,EACjD,SAAS,KAAc;AACrB,UAAM,QAAQ;AACd,QAAI,MAAM,SAAS,UAAU;AAC3B,YAAM,eAAe;AACrB,wBAAkB,OAAO,KAAK,YAAY;AAC1C,aAAO,KAAK,SAAS,YAAY,KAAK,cAAc,GAAG;AAAA,IACzD,OAAO;AACL,YAAM,eAAe;AACrB,wBAAkB,OAAO,KAAK,YAAY;AAC1C,aAAO,MAAM,SAAS,YAAY,IAAI,GAAG;AAAA,IAC3C;AAAA,EACF;AACF;AAEA,SAAS,kBAAkB,OAAqB,MAAc,SAAiB;AAC7E,QAAM,OAAO,IAAI,EAAE,KAAK,WAAW,EAAE,KAAK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,aAM/B,IAAI,KAAK,OAAO;AAAA;AAAA,QAErB,IAAI,KAAK,OAAO;AAAA,QAChB;AACR;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -2,7 +2,7 @@ import path from "path";
|
|
|
2
2
|
import { createWriteStream } from "fs";
|
|
3
3
|
import { pipeline } from "stream/promises";
|
|
4
4
|
import { Uuid } from "@simplysm/core-common";
|
|
5
|
-
import {
|
|
5
|
+
import { fsx } from "@simplysm/core-node";
|
|
6
6
|
import { verifyJwt } from "../../auth/jwt-manager.js";
|
|
7
7
|
import consola from "consola";
|
|
8
8
|
const logger = consola.withTag("service-server:UploadHandler");
|
|
@@ -30,20 +30,20 @@ async function handleUpload(req, reply, rootPath, jwtSecret) {
|
|
|
30
30
|
}
|
|
31
31
|
const result = [];
|
|
32
32
|
const uploadDir = path.resolve(rootPath, "www", "uploads");
|
|
33
|
-
await
|
|
33
|
+
await fsx.mkdir(uploadDir);
|
|
34
34
|
let currentSavePath;
|
|
35
35
|
try {
|
|
36
36
|
for await (const part of req.parts()) {
|
|
37
37
|
if (part.type === "file") {
|
|
38
38
|
const originalFilename = part.filename;
|
|
39
39
|
const extension = path.extname(originalFilename);
|
|
40
|
-
const saveName = `${Uuid.
|
|
40
|
+
const saveName = `${Uuid.generate().toString()}${extension}`;
|
|
41
41
|
currentSavePath = path.join(uploadDir, saveName);
|
|
42
42
|
await pipeline(part.file, createWriteStream(currentSavePath));
|
|
43
43
|
if (part.file.truncated) {
|
|
44
44
|
throw new Error(`File limit exceeded: ${originalFilename}`);
|
|
45
45
|
}
|
|
46
|
-
const stats = await
|
|
46
|
+
const stats = await fsx.stat(currentSavePath);
|
|
47
47
|
result.push({
|
|
48
48
|
path: `uploads/${saveName}`,
|
|
49
49
|
filename: originalFilename,
|
|
@@ -56,7 +56,7 @@ async function handleUpload(req, reply, rootPath, jwtSecret) {
|
|
|
56
56
|
} catch (err) {
|
|
57
57
|
logger.error("Upload Error", err);
|
|
58
58
|
if (currentSavePath != null) {
|
|
59
|
-
await
|
|
59
|
+
await fsx.rm(currentSavePath).catch(() => {
|
|
60
60
|
});
|
|
61
61
|
logger.warn(`Incomplete file deleted: ${currentSavePath}`);
|
|
62
62
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/transport/http/upload-handler.ts"],
|
|
4
|
-
"mappings": "AAAA,OAAO,UAAU;AACjB,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,SAAS,
|
|
4
|
+
"mappings": "AAAA,OAAO,UAAU;AACjB,SAAS,yBAAyB;AAClC,SAAS,gBAAgB;AACzB,SAAS,YAAY;AACrB,SAAS,WAAW;AAGpB,SAAS,iBAAiB;AAC1B,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,8BAA8B;AAE7D,eAAsB,aACpB,KACA,OACA,UACA,WACe;AACf,MAAI,CAAC,IAAI,YAAY,GAAG;AACtB,UAAM,OAAO,GAAG,EAAE,KAAK,4BAA4B;AACnD;AAAA,EACF;AAGA,MAAI;AACF,UAAM,aAAa,IAAI,QAAQ;AAC/B,QAAI,cAAc,MAAM;AACtB,YAAM,IAAI,MAAM,kCAAkC;AAAA,IACpD;AACA,QAAI,aAAa,MAAM;AACrB,YAAM,IAAI,MAAM,4BAA4B;AAAA,IAC9C;AACA,UAAM,QAAQ,WAAW,MAAM,GAAG,EAAE,CAAC;AACrC,UAAM,UAAU,WAAW,KAAK;AAAA,EAClC,SAAS,KAAK;AACZ,UAAM,OAAO,GAAG,EAAE,KAAK;AAAA,MACrB,OAAO;AAAA,MACP,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAAA,IAC1D,CAAC;AACD;AAAA,EACF;AAEA,QAAM,SAAgC,CAAC;AACvC,QAAM,YAAY,KAAK,QAAQ,UAAU,OAAO,SAAS;AAEzD,QAAM,IAAI,MAAM,SAAS;AAEzB,MAAI;AAEJ,MAAI;AACF,qBAAiB,QAAQ,IAAI,MAAM,GAAG;AACpC,UAAI,KAAK,SAAS,QAAQ;AACxB,cAAM,mBAAmB,KAAK;AAC9B,cAAM,YAAY,KAAK,QAAQ,gBAAgB;AAC/C,cAAM,WAAW,GAAG,KAAK,SAAS,EAAE,SAAS,CAAC,GAAG,SAAS;AAC1D,0BAAkB,KAAK,KAAK,WAAW,QAAQ;AAE/C,cAAM,SAAS,KAAK,MAAM,kBAAkB,eAAe,CAAC;AAE5D,YAAI,KAAK,KAAK,WAAW;AACvB,gBAAM,IAAI,MAAM,wBAAwB,gBAAgB,EAAE;AAAA,QAC5D;AAEA,cAAM,QAAQ,MAAM,IAAI,KAAK,eAAe;AAE5C,eAAO,KAAK;AAAA,UACV,MAAM,WAAW,QAAQ;AAAA,UACzB,UAAU;AAAA,UACV,MAAM,MAAM;AAAA,QACd,CAAC;AAED,0BAAkB;AAAA,MACpB;AAAA,IACF;AAEA,UAAM,KAAK,MAAM;AAAA,EACnB,SAAS,KAAK;AACZ,WAAO,MAAM,gBAAgB,GAAG;AAEhC,QAAI,mBAAmB,MAAM;AAC3B,YAAM,IAAI,GAAG,eAAe,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAC5C,aAAO,KAAK,4BAA4B,eAAe,EAAE;AAAA,IAC3D;AAEA,UAAM,KAAK,GAAG,EAAE,KAAK,eAAe;AAAA,EACtC;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -25,11 +25,11 @@ export interface ServiceSocket {
|
|
|
25
25
|
/**
|
|
26
26
|
* Register an event listener with key/name/info
|
|
27
27
|
*/
|
|
28
|
-
|
|
28
|
+
addListener(key: string, eventName: string, info: unknown): void;
|
|
29
29
|
/**
|
|
30
30
|
* Remove an event listener by key
|
|
31
31
|
*/
|
|
32
|
-
|
|
32
|
+
removeListener(key: string): void;
|
|
33
33
|
/**
|
|
34
34
|
* Get all event listeners for a specific event name
|
|
35
35
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service-socket.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\transport\\socket\\service-socket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EAErB,MAAM,0BAA0B,CAAC;AAIlC;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/D;;OAEG;IACH,
|
|
1
|
+
{"version":3,"file":"service-socket.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\transport\\socket\\service-socket.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAG9C,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,OAAO,KAAK,EACV,oBAAoB,EACpB,oBAAoB,EAErB,MAAM,0BAA0B,CAAC;AAIlC;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC;IACvC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC;;OAEG;IACH,KAAK,IAAI,IAAI,CAAC;IAEd;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,oBAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAE/D;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAEjE;;OAEG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IAElC;;OAEG;IACH,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;IAE5E;;OAEG;IACH,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IAEtD;;OAEG;IACH,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,CAAC;IACxD,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1D,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,oBAAoB,CAAA;KAAE,KAAK,IAAI,GAAG,IAAI,CAAC;CAClG;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,cAAc,GACtB,aAAa,CAgKf"}
|
|
@@ -2,12 +2,12 @@ import { DateTime } from "@simplysm/core-common";
|
|
|
2
2
|
import { clearInterval } from "node:timers";
|
|
3
3
|
import consola from "consola";
|
|
4
4
|
import { WebSocket } from "ws";
|
|
5
|
-
import {
|
|
5
|
+
import { createServerProtocolWrapper } from "../../protocol/protocol-wrapper.js";
|
|
6
6
|
const logger = consola.withTag("service-server:ServiceSocket");
|
|
7
7
|
function createServiceSocket(socket, clientId, clientName, connReq) {
|
|
8
8
|
const PING_INTERVAL = 5e3;
|
|
9
9
|
const PONG_PACKET = new Uint8Array([2]);
|
|
10
|
-
const protocol =
|
|
10
|
+
const protocol = createServerProtocolWrapper();
|
|
11
11
|
const listenerInfos = [];
|
|
12
12
|
const eventHandlers = {
|
|
13
13
|
error: [],
|
|
@@ -94,10 +94,10 @@ function createServiceSocket(socket, clientId, clientName, connReq) {
|
|
|
94
94
|
async send(uuid, msg) {
|
|
95
95
|
return sendInternal(uuid, msg);
|
|
96
96
|
},
|
|
97
|
-
|
|
97
|
+
addListener(key, eventName, info) {
|
|
98
98
|
listenerInfos.push({ key, eventName, info });
|
|
99
99
|
},
|
|
100
|
-
|
|
100
|
+
removeListener(key) {
|
|
101
101
|
const idx = listenerInfos.findIndex((item) => item.key === key);
|
|
102
102
|
if (idx >= 0) {
|
|
103
103
|
listenerInfos.splice(idx, 1);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/transport/socket/service-socket.ts"],
|
|
4
|
-
"mappings": "AACA,SAAS,gBAAgB;AAEzB,SAAS,qBAAqB;AAC9B,OAAO,aAAa;AACpB,SAAS,iBAAiB;AAE1B,SAAS,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -22,9 +22,9 @@ export interface WebSocketHandler {
|
|
|
22
22
|
*/
|
|
23
23
|
broadcastReload(clientName: string | undefined, changedFileSet: Set<string>): Promise<void>;
|
|
24
24
|
/**
|
|
25
|
-
* Emit event to
|
|
25
|
+
* Emit event to matching clients
|
|
26
26
|
*/
|
|
27
|
-
|
|
27
|
+
emit<TInfo, TData>(eventDef: ServiceEventDef<TInfo, TData>, infoSelector: (item: TInfo) => boolean, data: TData): Promise<void>;
|
|
28
28
|
}
|
|
29
29
|
/**
|
|
30
30
|
* Create a WebSocket handler instance
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-handler.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\transport\\socket\\websocket-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,OAAO,KAAK,EAAE,eAAe,EAAwB,MAAM,0BAA0B,CAAC;AACtF,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAElG;;OAEG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F;;OAEG;IACH,
|
|
1
|
+
{"version":3,"file":"websocket-handler.d.ts","sourceRoot":"","sources":["..\\..\\..\\src\\transport\\socket\\websocket-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAEpC,OAAO,KAAK,EAAE,eAAe,EAAwB,MAAM,0BAA0B,CAAC;AACtF,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAK9C;;;;;GAKG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,IAAI,CAAC;IAElG;;OAEG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;OAEG;IACH,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE5F;;OAEG;IACH,IAAI,CAAC,KAAK,EAAE,KAAK,EACf,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,EACvC,YAAY,EAAE,CAAC,IAAI,EAAE,KAAK,KAAK,OAAO,EACtC,IAAI,EAAE,KAAK,GACV,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,CAAC,GAAG,EAAE;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB,KAAK,OAAO,CAAC,OAAO,CAAC,EACtB,SAAS,EAAE,MAAM,GAAG,SAAS,GAC5B,gBAAgB,CAkMlB"}
|
|
@@ -18,11 +18,11 @@ function createWebSocketHandler(runMethod, jwtSecret) {
|
|
|
18
18
|
return await serviceSocket.send(uuid, { name: "response", body: result });
|
|
19
19
|
} else if (message.name === "evt:add") {
|
|
20
20
|
const { key, name, info } = message.body;
|
|
21
|
-
serviceSocket.
|
|
21
|
+
serviceSocket.addListener(key, name, info);
|
|
22
22
|
return await serviceSocket.send(uuid, { name: "response" });
|
|
23
23
|
} else if (message.name === "evt:remove") {
|
|
24
24
|
const { key } = message.body;
|
|
25
|
-
serviceSocket.
|
|
25
|
+
serviceSocket.removeListener(key);
|
|
26
26
|
return await serviceSocket.send(uuid, { name: "response" });
|
|
27
27
|
} else if (message.name === "evt:gets") {
|
|
28
28
|
const { name } = message.body;
|
|
@@ -115,7 +115,7 @@ function createWebSocketHandler(runMethod, jwtSecret) {
|
|
|
115
115
|
},
|
|
116
116
|
async broadcastReload(clientName, changedFileSet) {
|
|
117
117
|
for (const serviceSocket of socketMap.values()) {
|
|
118
|
-
await serviceSocket.send(Uuid.
|
|
118
|
+
await serviceSocket.send(Uuid.generate().toString(), {
|
|
119
119
|
name: "reload",
|
|
120
120
|
body: {
|
|
121
121
|
clientName,
|
|
@@ -124,13 +124,13 @@ function createWebSocketHandler(runMethod, jwtSecret) {
|
|
|
124
124
|
});
|
|
125
125
|
}
|
|
126
126
|
},
|
|
127
|
-
async
|
|
127
|
+
async emit(eventDef, infoSelector, data) {
|
|
128
128
|
const eventName = eventDef.eventName;
|
|
129
129
|
const targetKeys = Array.from(socketMap.values()).flatMap((subSock) => subSock.getEventListeners(eventName)).filter((item) => infoSelector(item.info)).map((item) => item.key);
|
|
130
130
|
for (const subSock of socketMap.values()) {
|
|
131
131
|
const subTargetKeys = subSock.filterEventTargetKeys(targetKeys);
|
|
132
132
|
if (subTargetKeys.length > 0) {
|
|
133
|
-
await subSock.send(Uuid.
|
|
133
|
+
await subSock.send(Uuid.generate().toString(), {
|
|
134
134
|
name: "evt:on",
|
|
135
135
|
body: {
|
|
136
136
|
keys: subTargetKeys,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/transport/socket/websocket-handler.ts"],
|
|
4
|
-
"mappings": "AACA,SAAS,YAAY;AAErB,SAAS,2BAA+C;AACxD,SAAS,iBAAiB;AAE1B,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,iCAAiC;AAwCzD,SAAS,uBACd,WAMA,WACkB;AAKlB,QAAM,YAAY,oBAAI,IAA2B;AAMjD,iBAAe,eACb,eACA,MACA,SACiB;AACjB,QAAI;AACF,UAAI,QAAQ,KAAK,SAAS,GAAG,KAAK,MAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7D,cAAM,CAAC,aAAa,UAAU,IAAI,QAAQ,KAAK,MAAM,GAAG;AAExD,cAAM,SAAS,MAAM,UAAU;AAAA,UAC7B;AAAA,UACA;AAAA,UACA,QAAQ,QAAQ;AAAA,UAChB,QAAQ;AAAA,QACV,CAAC;AAED,eAAO,MAAM,cAAc,KAAK,MAAM,EAAE,MAAM,YAAY,MAAM,OAAO,CAAC;AAAA,MAC1E,WAAW,QAAQ,SAAS,WAAW;AACrC,cAAM,EAAE,KAAK,MAAM,KAAK,IAAI,QAAQ;AACpC,sBAAc,
|
|
4
|
+
"mappings": "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",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LazyGcMap } from "@simplysm/core-common";
|
|
2
|
-
import {
|
|
2
|
+
import { fsx, FsWatcher } from "@simplysm/core-node";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
const logger = consola.withTag("service-server:ConfigManager");
|
|
@@ -18,22 +18,22 @@ async function getConfig(filePath) {
|
|
|
18
18
|
if (_cache.has(filePath)) {
|
|
19
19
|
return _cache.get(filePath);
|
|
20
20
|
}
|
|
21
|
-
if (!await
|
|
22
|
-
const config = await
|
|
21
|
+
if (!await fsx.exists(filePath)) return void 0;
|
|
22
|
+
const config = await fsx.readJson(filePath);
|
|
23
23
|
_cache.set(filePath, config);
|
|
24
24
|
if (!_watchers.has(filePath)) {
|
|
25
25
|
try {
|
|
26
26
|
const watcher = await FsWatcher.watch([filePath]);
|
|
27
27
|
_watchers.set(filePath, watcher);
|
|
28
28
|
watcher.onChange({ delay: 100 }, async () => {
|
|
29
|
-
if (!await
|
|
29
|
+
if (!await fsx.exists(filePath)) {
|
|
30
30
|
_cache.delete(filePath);
|
|
31
31
|
await closeWatcher(filePath);
|
|
32
32
|
logger.debug(`Config file deleted: ${path.basename(filePath)}`);
|
|
33
33
|
return;
|
|
34
34
|
}
|
|
35
35
|
try {
|
|
36
|
-
const newConfig = await
|
|
36
|
+
const newConfig = await fsx.readJson(filePath);
|
|
37
37
|
_cache.set(filePath, newConfig);
|
|
38
38
|
logger.debug(`Config file live-reloaded: ${path.basename(filePath)}`);
|
|
39
39
|
} catch (err) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/utils/config-manager.ts"],
|
|
4
|
-
"mappings": "AAAA,SAAS,iBAAiB;AAC1B,SAAS,
|
|
4
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAC1B,SAAS,KAAK,iBAAiB;AAC/B,OAAO,UAAU;AACjB,OAAO,aAAa;AAEpB,MAAM,SAAS,QAAQ,QAAQ,8BAA8B;AAG7D,MAAM,SAAS,IAAI,UAA2B;AAAA,EAC5C,YAAY,KAAK,KAAK;AAAA;AAAA,EACtB,YAAY,KAAK,KAAK;AAAA;AAAA,EACtB,UAAU,OAAO,aAAa;AAC5B,WAAO,MAAM,8CAA8C,KAAK,SAAS,QAAQ,CAAC,EAAE;AACpF,UAAM,aAAa,QAAQ;AAAA,EAC7B;AACF,CAAC;AAED,MAAM,YAAY,oBAAI,IAAuB;AAE7C,eAAsB,UAAmB,UAAgD;AAEvF,MAAI,OAAO,IAAI,QAAQ,GAAG;AACxB,WAAO,OAAO,IAAI,QAAQ;AAAA,EAC5B;AAEA,MAAI,CAAE,MAAM,IAAI,OAAO,QAAQ,EAAI,QAAO;AAG1C,QAAM,SAAS,MAAM,IAAI,SAAS,QAAQ;AAC1C,SAAO,IAAI,UAAU,MAAM;AAG3B,MAAI,CAAC,UAAU,IAAI,QAAQ,GAAG;AAC5B,QAAI;AACF,YAAM,UAAU,MAAM,UAAU,MAAM,CAAC,QAAQ,CAAC;AAChD,gBAAU,IAAI,UAAU,OAAO;AAE/B,cAAQ,SAAS,EAAE,OAAO,IAAI,GAAG,YAAY;AAC3C,YAAI,CAAE,MAAM,IAAI,OAAO,QAAQ,GAAI;AACjC,iBAAO,OAAO,QAAQ;AACtB,gBAAM,aAAa,QAAQ;AAC3B,iBAAO,MAAM,wBAAwB,KAAK,SAAS,QAAQ,CAAC,EAAE;AAC9D;AAAA,QACF;AAEA,YAAI;AACF,gBAAM,YAAY,MAAM,IAAI,SAAS,QAAQ;AAC7C,iBAAO,IAAI,UAAU,SAAS;AAC9B,iBAAO,MAAM,8BAA8B,KAAK,SAAS,QAAQ,CAAC,EAAE;AAAA,QACtE,SAAS,KAAK;AACZ,iBAAO,KAAK,8BAA8B,QAAQ,IAAI,GAAG;AAAA,QAC3D;AAAA,MACF,CAAC;AAAA,IACH,SAAS,KAAK;AACZ,aAAO,MAAM,iBAAiB,QAAQ,IAAI,GAAG;AAAA,IAC/C;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,aAAa,UAAkB;AAC5C,QAAM,UAAU,UAAU,IAAI,QAAQ;AACtC,MAAI,WAAW,MAAM;AACnB,UAAM,QAAQ,MAAM;AACpB,cAAU,OAAO,QAAQ;AAAA,EAC3B;AACF;",
|
|
5
5
|
"names": []
|
|
6
6
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Bytes } from "@simplysm/core-common";
|
|
2
2
|
import type { ServiceMessageDecodeResult, ServiceMessage } from "@simplysm/service-common";
|
|
3
3
|
declare const _default: {
|
|
4
|
-
send<
|
|
4
|
+
send<TEventName extends string>(event: TEventName, data?: undefined): void;
|
|
5
5
|
__methods: {
|
|
6
6
|
encode: (uuid: string, message: ServiceMessage) => {
|
|
7
7
|
chunks: Bytes[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simplysm/service-server",
|
|
3
|
-
"version": "13.0.
|
|
3
|
+
"version": "13.0.77",
|
|
4
4
|
"description": "Simplysm package - service module (server)",
|
|
5
5
|
"author": "simplysm",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -35,11 +35,11 @@
|
|
|
35
35
|
"semver": "^7.7.4",
|
|
36
36
|
"utf-8-validate": "^6.0.6",
|
|
37
37
|
"ws": "^8.19.0",
|
|
38
|
-
"@simplysm/
|
|
39
|
-
"@simplysm/
|
|
40
|
-
"@simplysm/
|
|
41
|
-
"@simplysm/
|
|
42
|
-
"@simplysm/service-common": "13.0.
|
|
38
|
+
"@simplysm/core-common": "13.0.77",
|
|
39
|
+
"@simplysm/core-node": "13.0.77",
|
|
40
|
+
"@simplysm/orm-common": "13.0.77",
|
|
41
|
+
"@simplysm/orm-node": "13.0.77",
|
|
42
|
+
"@simplysm/service-common": "13.0.77"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
45
|
"@types/nodemailer": "^6.4.23",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ServiceServer } from "../service-server";
|
|
2
2
|
import type { ServiceSocket } from "../transport/socket/service-socket";
|
|
3
3
|
import type { AuthTokenPayload } from "../auth/auth-token-payload";
|
|
4
|
-
import {
|
|
4
|
+
import { obj } from "@simplysm/core-common";
|
|
5
5
|
import { getConfig } from "../utils/config-manager";
|
|
6
6
|
import path from "path";
|
|
7
7
|
|
|
@@ -74,7 +74,7 @@ export function createServiceContext<TAuthInfo = unknown>(
|
|
|
74
74
|
const clientFilePath = path.resolve(targetPath, ".config.json");
|
|
75
75
|
const clientConfig = await getConfig<Record<string, T>>(clientFilePath);
|
|
76
76
|
if (clientConfig != null) {
|
|
77
|
-
configParent =
|
|
77
|
+
configParent = obj.merge(configParent, clientConfig);
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -3,7 +3,7 @@ import type { ServiceSocket } from "../transport/socket/service-socket";
|
|
|
3
3
|
import type { AuthTokenPayload } from "../auth/auth-token-payload";
|
|
4
4
|
import { createServiceContext, getServiceAuthPermissions } from "./define-service";
|
|
5
5
|
|
|
6
|
-
export async function
|
|
6
|
+
export async function executeServiceMethod(
|
|
7
7
|
server: ServiceServer,
|
|
8
8
|
def: {
|
|
9
9
|
serviceName: string;
|
|
@@ -10,7 +10,7 @@ import type * as ServiceProtocolWorkerModule from "../workers/service-protocol.w
|
|
|
10
10
|
* Automatically offloads heavy message encoding/decoding to a worker thread
|
|
11
11
|
* while using main thread for lightweight operations.
|
|
12
12
|
*/
|
|
13
|
-
export interface
|
|
13
|
+
export interface ServerProtocolWrapper {
|
|
14
14
|
/**
|
|
15
15
|
* Encode message (auto worker delegation)
|
|
16
16
|
*/
|
|
@@ -48,7 +48,7 @@ function getWorker(): WorkerProxy<typeof ServiceProtocolWorkerModule> {
|
|
|
48
48
|
* Automatically offloads heavy message encoding/decoding to a worker thread
|
|
49
49
|
* while using main thread for lightweight operations.
|
|
50
50
|
*/
|
|
51
|
-
export function
|
|
51
|
+
export function createServerProtocolWrapper(): ServerProtocolWrapper {
|
|
52
52
|
// -------------------------------------------------------------------
|
|
53
53
|
// State
|
|
54
54
|
// -------------------------------------------------------------------
|
package/src/service-server.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { ServiceEventDef } from "@simplysm/service-common";
|
|
2
2
|
import { handleStaticFile } from "./transport/http/static-file-handler";
|
|
3
3
|
import { handleHttpRequest } from "./transport/http/http-request-handler";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { executeServiceMethod } from "./core/service-executor";
|
|
5
|
+
import { json, EventEmitter, env } from "@simplysm/core-common";
|
|
6
6
|
import type { FastifyInstance, FastifyRequest } from "fastify";
|
|
7
7
|
import fastify from "fastify";
|
|
8
8
|
import fastifyWebsocket from "@fastify/websocket";
|
|
@@ -46,7 +46,7 @@ export class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
|
|
|
46
46
|
this.fastify = fastify({ https: httpsConf });
|
|
47
47
|
|
|
48
48
|
this._wsHandler = createWebSocketHandler(
|
|
49
|
-
(def) =>
|
|
49
|
+
(def) => executeServiceMethod(this, def),
|
|
50
50
|
options.auth?.jwtSecret,
|
|
51
51
|
);
|
|
52
52
|
}
|
|
@@ -103,8 +103,8 @@ export class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
|
|
|
103
103
|
{ parseAs: "string" },
|
|
104
104
|
(req, body, done) => {
|
|
105
105
|
try {
|
|
106
|
-
const
|
|
107
|
-
done(null,
|
|
106
|
+
const parsed = json.parse(body as string);
|
|
107
|
+
done(null, parsed);
|
|
108
108
|
} catch (err: unknown) {
|
|
109
109
|
const error = err as Error & { statusCode?: number };
|
|
110
110
|
error.statusCode = 400;
|
|
@@ -114,12 +114,12 @@ export class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
|
|
|
114
114
|
);
|
|
115
115
|
|
|
116
116
|
// JSON serializer
|
|
117
|
-
this.fastify.setSerializerCompiler(() => (data) =>
|
|
117
|
+
this.fastify.setSerializerCompiler(() => (data) => json.stringify(data));
|
|
118
118
|
|
|
119
119
|
// API routes
|
|
120
120
|
this.fastify.all("/api/:service/:method", async (req, reply) => {
|
|
121
121
|
await handleHttpRequest(req, reply, this.options.auth?.jwtSecret, (def) =>
|
|
122
|
-
|
|
122
|
+
executeServiceMethod(this, def),
|
|
123
123
|
);
|
|
124
124
|
});
|
|
125
125
|
|
|
@@ -210,10 +210,10 @@ export class ServiceServer<TAuthInfo = unknown> extends EventEmitter<{
|
|
|
210
210
|
infoSelector: (item: TInfo) => boolean,
|
|
211
211
|
data: TData,
|
|
212
212
|
) {
|
|
213
|
-
await this._wsHandler.
|
|
213
|
+
await this._wsHandler.emit(eventDef, infoSelector, data);
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
async
|
|
216
|
+
async signAuthToken(payload: AuthTokenPayload<TAuthInfo>) {
|
|
217
217
|
const jwtSecret = this.options.auth?.jwtSecret;
|
|
218
218
|
if (jwtSecret == null) throw new Error("JWT Secret is not defined.");
|
|
219
219
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import path from "path";
|
|
2
2
|
import semver from "semver";
|
|
3
|
-
import {
|
|
3
|
+
import { fsx, pathx } from "@simplysm/core-node";
|
|
4
4
|
import { defineService, type ServiceMethods } from "../core/define-service";
|
|
5
5
|
|
|
6
6
|
export const AutoUpdateService = defineService("AutoUpdate", (ctx) => ({
|
|
@@ -14,9 +14,9 @@ export const AutoUpdateService = defineService("AutoUpdate", (ctx) => ({
|
|
|
14
14
|
const clientPath = ctx.clientPath;
|
|
15
15
|
if (clientPath == null) throw new Error("Client path not found.");
|
|
16
16
|
|
|
17
|
-
if (!(await
|
|
17
|
+
if (!(await fsx.exists(path.resolve(clientPath, platform, "updates")))) return undefined;
|
|
18
18
|
|
|
19
|
-
const updates = await
|
|
19
|
+
const updates = await fsx.readdir(path.resolve(clientPath, platform, "updates"));
|
|
20
20
|
const versions = updates
|
|
21
21
|
.map((item) => ({
|
|
22
22
|
fileName: item,
|
|
@@ -42,7 +42,7 @@ export const AutoUpdateService = defineService("AutoUpdate", (ctx) => ({
|
|
|
42
42
|
if (versionItem == null) return undefined;
|
|
43
43
|
|
|
44
44
|
const downloadPath =
|
|
45
|
-
"/" +
|
|
45
|
+
"/" + pathx.posix(ctx.clientName ?? "", platform, "updates", versionItem.fileName);
|
|
46
46
|
|
|
47
47
|
return {
|
|
48
48
|
version: version.toString(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import nodemailer from "nodemailer";
|
|
2
2
|
import { defineService, type ServiceMethods } from "../core/define-service";
|
|
3
3
|
import type {
|
|
4
|
-
|
|
4
|
+
SmtpClientDefaultOptions,
|
|
5
5
|
SmtpClientSendByDefaultOption,
|
|
6
6
|
SmtpClientSendOption,
|
|
7
7
|
} from "@simplysm/service-common";
|
|
@@ -38,7 +38,7 @@ export const SmtpClientService = defineService("SmtpClient", (ctx) => ({
|
|
|
38
38
|
|
|
39
39
|
async sendByConfig(configName: string, options: SmtpClientSendByDefaultOption): Promise<string> {
|
|
40
40
|
const config = (
|
|
41
|
-
await ctx.getConfig<Record<string,
|
|
41
|
+
await ctx.getConfig<Record<string, SmtpClientDefaultOptions | undefined>>("smtp")
|
|
42
42
|
)[configName];
|
|
43
43
|
if (config == null) {
|
|
44
44
|
throw new Error(`SMTP config not found: ${configName}`);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { json } from "@simplysm/core-common";
|
|
2
2
|
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
3
3
|
import { verifyJwt } from "../../auth/jwt-manager";
|
|
4
4
|
import type { AuthTokenPayload } from "../../auth/auth-token-payload";
|
|
@@ -45,7 +45,7 @@ export async function handleHttpRequest<TAuthInfo = unknown>(
|
|
|
45
45
|
if (typeof query.json !== "string") {
|
|
46
46
|
throw new Error("JSON query parameter required");
|
|
47
47
|
}
|
|
48
|
-
params =
|
|
48
|
+
params = json.parse(query.json);
|
|
49
49
|
} else if (req.method === "POST") {
|
|
50
50
|
if (!Array.isArray(req.body)) {
|
|
51
51
|
reply.status(400).send({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import path from "path";
|
|
2
|
-
import {
|
|
2
|
+
import { fsx, pathx } from "@simplysm/core-node";
|
|
3
3
|
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
|
|
@@ -15,12 +15,12 @@ export async function handleStaticFile(
|
|
|
15
15
|
const allowedRootPath = path.resolve(rootPath, "www");
|
|
16
16
|
|
|
17
17
|
// Security guard for targetPath (prevent path traversal)
|
|
18
|
-
if (targetFilePath !== allowedRootPath && !
|
|
18
|
+
if (targetFilePath !== allowedRootPath && !pathx.isChildPath(targetFilePath, allowedRootPath)) {
|
|
19
19
|
throw new Error("Access denied");
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
// Redirect with trailing slash for directories (standard web server behavior)
|
|
23
|
-
if ((await
|
|
23
|
+
if ((await fsx.exists(targetFilePath)) && (await fsx.stat(targetFilePath)).isDirectory()) {
|
|
24
24
|
if (!urlPath.endsWith("/")) {
|
|
25
25
|
const urlObj = new URL(req.raw.url!, "http://localhost");
|
|
26
26
|
reply.redirect(urlObj.pathname + "/" + urlObj.search);
|
|
@@ -2,7 +2,7 @@ import path from "path";
|
|
|
2
2
|
import { createWriteStream } from "fs";
|
|
3
3
|
import { pipeline } from "stream/promises";
|
|
4
4
|
import { Uuid } from "@simplysm/core-common";
|
|
5
|
-
import {
|
|
5
|
+
import { fsx } from "@simplysm/core-node";
|
|
6
6
|
import type { FastifyReply, FastifyRequest } from "fastify";
|
|
7
7
|
import type { ServiceUploadResult } from "@simplysm/service-common";
|
|
8
8
|
import { verifyJwt } from "../../auth/jwt-manager";
|
|
@@ -43,7 +43,7 @@ export async function handleUpload(
|
|
|
43
43
|
const result: ServiceUploadResult[] = [];
|
|
44
44
|
const uploadDir = path.resolve(rootPath, "www", "uploads");
|
|
45
45
|
|
|
46
|
-
await
|
|
46
|
+
await fsx.mkdir(uploadDir);
|
|
47
47
|
|
|
48
48
|
let currentSavePath: string | undefined;
|
|
49
49
|
|
|
@@ -52,7 +52,7 @@ export async function handleUpload(
|
|
|
52
52
|
if (part.type === "file") {
|
|
53
53
|
const originalFilename = part.filename;
|
|
54
54
|
const extension = path.extname(originalFilename);
|
|
55
|
-
const saveName = `${Uuid.
|
|
55
|
+
const saveName = `${Uuid.generate().toString()}${extension}`;
|
|
56
56
|
currentSavePath = path.join(uploadDir, saveName);
|
|
57
57
|
|
|
58
58
|
await pipeline(part.file, createWriteStream(currentSavePath));
|
|
@@ -61,7 +61,7 @@ export async function handleUpload(
|
|
|
61
61
|
throw new Error(`File limit exceeded: ${originalFilename}`);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
const stats = await
|
|
64
|
+
const stats = await fsx.stat(currentSavePath);
|
|
65
65
|
|
|
66
66
|
result.push({
|
|
67
67
|
path: `uploads/${saveName}`,
|
|
@@ -78,7 +78,7 @@ export async function handleUpload(
|
|
|
78
78
|
logger.error("Upload Error", err);
|
|
79
79
|
|
|
80
80
|
if (currentSavePath != null) {
|
|
81
|
-
await
|
|
81
|
+
await fsx.rm(currentSavePath).catch(() => {});
|
|
82
82
|
logger.warn(`Incomplete file deleted: ${currentSavePath}`);
|
|
83
83
|
}
|
|
84
84
|
|
|
@@ -5,7 +5,7 @@ import { clearInterval } from "node:timers";
|
|
|
5
5
|
import consola from "consola";
|
|
6
6
|
import { WebSocket } from "ws";
|
|
7
7
|
import type { AuthTokenPayload } from "../../auth/auth-token-payload";
|
|
8
|
-
import {
|
|
8
|
+
import { createServerProtocolWrapper } from "../../protocol/protocol-wrapper";
|
|
9
9
|
import type {
|
|
10
10
|
ServiceClientMessage,
|
|
11
11
|
ServiceServerMessage,
|
|
@@ -39,12 +39,12 @@ export interface ServiceSocket {
|
|
|
39
39
|
/**
|
|
40
40
|
* Register an event listener with key/name/info
|
|
41
41
|
*/
|
|
42
|
-
|
|
42
|
+
addListener(key: string, eventName: string, info: unknown): void;
|
|
43
43
|
|
|
44
44
|
/**
|
|
45
45
|
* Remove an event listener by key
|
|
46
46
|
*/
|
|
47
|
-
|
|
47
|
+
removeListener(key: string): void;
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
50
|
* Get all event listeners for a specific event name
|
|
@@ -83,7 +83,7 @@ export function createServiceSocket(
|
|
|
83
83
|
const PING_INTERVAL = 5000; // Send ping every 5s
|
|
84
84
|
const PONG_PACKET = new Uint8Array([0x02]);
|
|
85
85
|
|
|
86
|
-
const protocol =
|
|
86
|
+
const protocol = createServerProtocolWrapper();
|
|
87
87
|
const listenerInfos: Array<{ eventName: string; key: string; info: unknown }> = [];
|
|
88
88
|
const eventHandlers = {
|
|
89
89
|
error: [] as Array<(err: Error) => void>,
|
|
@@ -210,11 +210,11 @@ export function createServiceSocket(
|
|
|
210
210
|
return sendInternal(uuid, msg);
|
|
211
211
|
},
|
|
212
212
|
|
|
213
|
-
|
|
213
|
+
addListener(key: string, eventName: string, info: unknown): void {
|
|
214
214
|
listenerInfos.push({ key, eventName, info });
|
|
215
215
|
},
|
|
216
216
|
|
|
217
|
-
|
|
217
|
+
removeListener(key: string): void {
|
|
218
218
|
const idx = listenerInfos.findIndex((item) => item.key === key);
|
|
219
219
|
if (idx >= 0) {
|
|
220
220
|
listenerInfos.splice(idx, 1);
|
|
@@ -31,9 +31,9 @@ export interface WebSocketHandler {
|
|
|
31
31
|
broadcastReload(clientName: string | undefined, changedFileSet: Set<string>): Promise<void>;
|
|
32
32
|
|
|
33
33
|
/**
|
|
34
|
-
* Emit event to
|
|
34
|
+
* Emit event to matching clients
|
|
35
35
|
*/
|
|
36
|
-
|
|
36
|
+
emit<TInfo, TData>(
|
|
37
37
|
eventDef: ServiceEventDef<TInfo, TData>,
|
|
38
38
|
infoSelector: (item: TInfo) => boolean,
|
|
39
39
|
data: TData,
|
|
@@ -84,11 +84,11 @@ export function createWebSocketHandler(
|
|
|
84
84
|
return await serviceSocket.send(uuid, { name: "response", body: result });
|
|
85
85
|
} else if (message.name === "evt:add") {
|
|
86
86
|
const { key, name, info } = message.body as { key: string; name: string; info: unknown };
|
|
87
|
-
serviceSocket.
|
|
87
|
+
serviceSocket.addListener(key, name, info);
|
|
88
88
|
return await serviceSocket.send(uuid, { name: "response" });
|
|
89
89
|
} else if (message.name === "evt:remove") {
|
|
90
90
|
const { key } = message.body as { key: string };
|
|
91
|
-
serviceSocket.
|
|
91
|
+
serviceSocket.removeListener(key);
|
|
92
92
|
return await serviceSocket.send(uuid, { name: "response" });
|
|
93
93
|
} else if (message.name === "evt:gets") {
|
|
94
94
|
const { name } = message.body as { name: string };
|
|
@@ -213,7 +213,7 @@ export function createWebSocketHandler(
|
|
|
213
213
|
changedFileSet: Set<string>,
|
|
214
214
|
): Promise<void> {
|
|
215
215
|
for (const serviceSocket of socketMap.values()) {
|
|
216
|
-
await serviceSocket.send(Uuid.
|
|
216
|
+
await serviceSocket.send(Uuid.generate().toString(), {
|
|
217
217
|
name: "reload",
|
|
218
218
|
body: {
|
|
219
219
|
clientName,
|
|
@@ -223,7 +223,7 @@ export function createWebSocketHandler(
|
|
|
223
223
|
}
|
|
224
224
|
},
|
|
225
225
|
|
|
226
|
-
async
|
|
226
|
+
async emit<TInfo, TData>(
|
|
227
227
|
eventDef: ServiceEventDef<TInfo, TData>,
|
|
228
228
|
infoSelector: (item: TInfo) => boolean,
|
|
229
229
|
data: TData,
|
|
@@ -237,7 +237,7 @@ export function createWebSocketHandler(
|
|
|
237
237
|
for (const subSock of socketMap.values()) {
|
|
238
238
|
const subTargetKeys = subSock.filterEventTargetKeys(targetKeys);
|
|
239
239
|
if (subTargetKeys.length > 0) {
|
|
240
|
-
await subSock.send(Uuid.
|
|
240
|
+
await subSock.send(Uuid.generate().toString(), {
|
|
241
241
|
name: "evt:on",
|
|
242
242
|
body: {
|
|
243
243
|
keys: subTargetKeys,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LazyGcMap } from "@simplysm/core-common";
|
|
2
|
-
import {
|
|
2
|
+
import { fsx, FsWatcher } from "@simplysm/core-node";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import consola from "consola";
|
|
5
5
|
|
|
@@ -23,10 +23,10 @@ export async function getConfig<TConfig>(filePath: string): Promise<TConfig | un
|
|
|
23
23
|
return _cache.get(filePath) as TConfig;
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
if (!(await
|
|
26
|
+
if (!(await fsx.exists(filePath))) return undefined;
|
|
27
27
|
|
|
28
28
|
// 2. Load and cache
|
|
29
|
-
const config = await
|
|
29
|
+
const config = await fsx.readJson(filePath);
|
|
30
30
|
_cache.set(filePath, config);
|
|
31
31
|
|
|
32
32
|
// 3. Register watcher
|
|
@@ -36,7 +36,7 @@ export async function getConfig<TConfig>(filePath: string): Promise<TConfig | un
|
|
|
36
36
|
_watchers.set(filePath, watcher);
|
|
37
37
|
|
|
38
38
|
watcher.onChange({ delay: 100 }, async () => {
|
|
39
|
-
if (!(await
|
|
39
|
+
if (!(await fsx.exists(filePath))) {
|
|
40
40
|
_cache.delete(filePath);
|
|
41
41
|
await closeWatcher(filePath);
|
|
42
42
|
logger.debug(`Config file deleted: ${path.basename(filePath)}`);
|
|
@@ -44,7 +44,7 @@ export async function getConfig<TConfig>(filePath: string): Promise<TConfig | un
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
try {
|
|
47
|
-
const newConfig = await
|
|
47
|
+
const newConfig = await fsx.readJson(filePath);
|
|
48
48
|
_cache.set(filePath, newConfig);
|
|
49
49
|
logger.debug(`Config file live-reloaded: ${path.basename(filePath)}`);
|
|
50
50
|
} catch (err) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from "vitest";
|
|
2
|
-
import {
|
|
2
|
+
import { executeServiceMethod } from "../src/core/service-executor";
|
|
3
3
|
import { defineService, auth } from "../src/core/define-service";
|
|
4
4
|
|
|
5
5
|
// Minimal mock server
|
|
@@ -7,14 +7,14 @@ function createMockServer(services: any[]) {
|
|
|
7
7
|
return { options: { services, auth: { jwtSecret: "test" } } } as any;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
describe("
|
|
10
|
+
describe("executeServiceMethod with ServiceDefinition", () => {
|
|
11
11
|
it("executes a basic service method", async () => {
|
|
12
12
|
const EchoService = defineService("Echo", (_ctx) => ({
|
|
13
13
|
echo: (msg: string) => `Echo: ${msg}`,
|
|
14
14
|
}));
|
|
15
15
|
|
|
16
16
|
const server = createMockServer([EchoService]);
|
|
17
|
-
const result = await
|
|
17
|
+
const result = await executeServiceMethod(server, {
|
|
18
18
|
serviceName: "Echo",
|
|
19
19
|
methodName: "echo",
|
|
20
20
|
params: ["hello"],
|
|
@@ -27,7 +27,7 @@ describe("runServiceMethod with ServiceDefinition", () => {
|
|
|
27
27
|
const server = createMockServer([]);
|
|
28
28
|
|
|
29
29
|
await expect(
|
|
30
|
-
|
|
30
|
+
executeServiceMethod(server, { serviceName: "Unknown", methodName: "test", params: [] }),
|
|
31
31
|
).rejects.toThrow("Service [Unknown] not found.");
|
|
32
32
|
});
|
|
33
33
|
|
|
@@ -38,7 +38,7 @@ describe("runServiceMethod with ServiceDefinition", () => {
|
|
|
38
38
|
const server = createMockServer([svc]);
|
|
39
39
|
|
|
40
40
|
await expect(
|
|
41
|
-
|
|
41
|
+
executeServiceMethod(server, { serviceName: "Test", methodName: "nonexistent", params: [] }),
|
|
42
42
|
).rejects.toThrow("Method [Test.nonexistent] not found.");
|
|
43
43
|
});
|
|
44
44
|
|
|
@@ -52,7 +52,7 @@ describe("runServiceMethod with ServiceDefinition", () => {
|
|
|
52
52
|
const server = createMockServer([svc]);
|
|
53
53
|
|
|
54
54
|
await expect(
|
|
55
|
-
|
|
55
|
+
executeServiceMethod(server, { serviceName: "Protected", methodName: "secret", params: [] }),
|
|
56
56
|
).rejects.toThrow("Login is required.");
|
|
57
57
|
});
|
|
58
58
|
|
|
@@ -68,7 +68,7 @@ describe("runServiceMethod with ServiceDefinition", () => {
|
|
|
68
68
|
|
|
69
69
|
// Has auth but wrong role
|
|
70
70
|
await expect(
|
|
71
|
-
|
|
71
|
+
executeServiceMethod(server, {
|
|
72
72
|
serviceName: "Admin",
|
|
73
73
|
methodName: "manage",
|
|
74
74
|
params: [],
|
|
@@ -86,7 +86,7 @@ describe("runServiceMethod with ServiceDefinition", () => {
|
|
|
86
86
|
);
|
|
87
87
|
const server = createMockServer([svc]);
|
|
88
88
|
|
|
89
|
-
const result = await
|
|
89
|
+
const result = await executeServiceMethod(server, {
|
|
90
90
|
serviceName: "Admin",
|
|
91
91
|
methodName: "manage",
|
|
92
92
|
params: [],
|
|
@@ -102,7 +102,7 @@ describe("runServiceMethod with ServiceDefinition", () => {
|
|
|
102
102
|
}));
|
|
103
103
|
const server = createMockServer([svc]);
|
|
104
104
|
|
|
105
|
-
const result = await
|
|
105
|
+
const result = await executeServiceMethod(server, {
|
|
106
106
|
serviceName: "Ctx",
|
|
107
107
|
methodName: "getClientName",
|
|
108
108
|
params: [],
|