@sockethub/server 5.0.0-alpha.11 → 5.0.0-alpha.12
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/defaults.json +4 -0
- package/dist/index.js +46734 -46237
- package/dist/index.js.map +198 -196
- package/dist/platform.js +17926 -1483
- package/dist/platform.js.map +180 -31
- package/package.json +14 -14
- package/res/sockethub-client.js +17452 -288
- package/res/sockethub-client.min.js +32 -4
- package/src/bootstrap/init.test-helpers.ts +75 -0
- package/src/bootstrap/init.test.ts +70 -106
- package/src/bootstrap/init.ts +45 -27
- package/src/bootstrap/load-platforms.ts +39 -8
- package/src/config.ts +12 -1
- package/src/defaults.json +4 -0
- package/src/index.ts +9 -7
- package/src/janitor.ts +3 -1
- package/src/listener.ts +8 -9
- package/src/middleware/create-activity-object.ts +1 -1
- package/src/middleware/expand-activity-stream.test.data.ts +30 -23
- package/src/middleware/expand-activity-stream.ts +11 -8
- package/src/middleware/store-credentials.test.ts +5 -1
- package/src/middleware/store-credentials.ts +11 -5
- package/src/middleware/validate.test.data.ts +132 -16
- package/src/middleware/validate.test.ts +6 -2
- package/src/middleware/validate.ts +137 -30
- package/src/middleware.ts +26 -22
- package/src/platform-instance.test.ts +41 -6
- package/src/platform-instance.ts +164 -25
- package/src/platform.test.ts +11 -2
- package/src/platform.ts +135 -19
- package/src/process-manager.ts +30 -4
- package/src/rate-limiter.ts +5 -1
- package/src/routes.ts +16 -8
- package/src/sockethub.ts +192 -83
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { mock } from "bun:test";
|
|
2
|
+
import type { IInitObject } from "./init.js";
|
|
3
|
+
import { __clearInit } from "./init.js";
|
|
4
|
+
import loadPlatforms from "./load-platforms.js";
|
|
5
|
+
|
|
6
|
+
function getFakePlatform(name: string) {
|
|
7
|
+
return class FakeSockethubPlatform {
|
|
8
|
+
get config() {
|
|
9
|
+
return {};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
get schema() {
|
|
13
|
+
return {
|
|
14
|
+
name: name,
|
|
15
|
+
version: "0.0.1",
|
|
16
|
+
contextUrl: `https://sockethub.org/ns/context/platform/${name}/v1.jsonld`,
|
|
17
|
+
contextVersion: "1",
|
|
18
|
+
schemaVersion: "1",
|
|
19
|
+
credentials: {
|
|
20
|
+
required: ["object"],
|
|
21
|
+
properties: {
|
|
22
|
+
actor: {
|
|
23
|
+
type: "object",
|
|
24
|
+
required: ["id"],
|
|
25
|
+
},
|
|
26
|
+
object: {
|
|
27
|
+
type: "object",
|
|
28
|
+
required: ["type", "user", "pass"],
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
properties: {
|
|
31
|
+
type: {
|
|
32
|
+
type: "string",
|
|
33
|
+
},
|
|
34
|
+
user: {
|
|
35
|
+
type: "string",
|
|
36
|
+
},
|
|
37
|
+
pass: {
|
|
38
|
+
type: "string",
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
messages: {
|
|
45
|
+
required: ["type"],
|
|
46
|
+
properties: {
|
|
47
|
+
type: {
|
|
48
|
+
enum: ["echo", "fail"],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export async function initMockFakePlatform(platformName: string) {
|
|
58
|
+
const initObject = {
|
|
59
|
+
version: "init object",
|
|
60
|
+
platforms: new Map(),
|
|
61
|
+
} as IInitObject;
|
|
62
|
+
__clearInit();
|
|
63
|
+
const initFunc = async () => {
|
|
64
|
+
const modules = {};
|
|
65
|
+
modules[platformName] = getFakePlatform(platformName);
|
|
66
|
+
initObject.platforms = await loadPlatforms(
|
|
67
|
+
[platformName],
|
|
68
|
+
async (module) => {
|
|
69
|
+
return Promise.resolve(modules[module]);
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
return Promise.resolve(initObject);
|
|
73
|
+
};
|
|
74
|
+
return mock(initFunc);
|
|
75
|
+
}
|
|
@@ -1,79 +1,10 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import * as sinon from "sinon";
|
|
1
|
+
import { beforeEach, describe, expect, it, mock } from "bun:test";
|
|
3
2
|
import getInitObject, {
|
|
4
3
|
__clearInit,
|
|
5
4
|
printSettingsInfo,
|
|
6
5
|
type IInitObject,
|
|
7
6
|
} from "./init.js";
|
|
8
|
-
import
|
|
9
|
-
|
|
10
|
-
function getFakePlatform(name: string) {
|
|
11
|
-
return class FakeSockethubPlatform {
|
|
12
|
-
get config() {
|
|
13
|
-
return {};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
get schema() {
|
|
17
|
-
return {
|
|
18
|
-
name: name,
|
|
19
|
-
version: "0.0.1",
|
|
20
|
-
credentials: {
|
|
21
|
-
required: ["object"],
|
|
22
|
-
properties: {
|
|
23
|
-
actor: {
|
|
24
|
-
type: "object",
|
|
25
|
-
required: ["id"],
|
|
26
|
-
},
|
|
27
|
-
object: {
|
|
28
|
-
type: "object",
|
|
29
|
-
required: ["type", "user", "pass"],
|
|
30
|
-
additionalProperties: false,
|
|
31
|
-
properties: {
|
|
32
|
-
type: {
|
|
33
|
-
type: "string",
|
|
34
|
-
},
|
|
35
|
-
user: {
|
|
36
|
-
type: "string",
|
|
37
|
-
},
|
|
38
|
-
pass: {
|
|
39
|
-
type: "string",
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
messages: {
|
|
46
|
-
required: ["type"],
|
|
47
|
-
properties: {
|
|
48
|
-
type: {
|
|
49
|
-
enum: ["echo", "fail"],
|
|
50
|
-
},
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
export async function initMockFakePlatform(platformName: string) {
|
|
59
|
-
const initObject = {
|
|
60
|
-
version: "init object",
|
|
61
|
-
platforms: new Map(),
|
|
62
|
-
} as IInitObject;
|
|
63
|
-
__clearInit();
|
|
64
|
-
const initFunc = async () => {
|
|
65
|
-
const modules = {};
|
|
66
|
-
modules[platformName] = getFakePlatform(platformName);
|
|
67
|
-
initObject.platforms = await loadPlatforms(
|
|
68
|
-
[platformName],
|
|
69
|
-
async (module) => {
|
|
70
|
-
return Promise.resolve(modules[module]);
|
|
71
|
-
},
|
|
72
|
-
);
|
|
73
|
-
return Promise.resolve(initObject);
|
|
74
|
-
};
|
|
75
|
-
return mock(initFunc);
|
|
76
|
-
}
|
|
7
|
+
import { initMockFakePlatform } from "./init.test-helpers.js";
|
|
77
8
|
|
|
78
9
|
describe("platformLoad", () => {
|
|
79
10
|
let loadInitMock;
|
|
@@ -126,32 +57,50 @@ describe("Init", () => {
|
|
|
126
57
|
});
|
|
127
58
|
|
|
128
59
|
describe("printSettingsInfo", () => {
|
|
129
|
-
let
|
|
130
|
-
let
|
|
60
|
+
let logs: Array<string>;
|
|
61
|
+
let exitCalled: boolean;
|
|
62
|
+
let exitMock: () => never;
|
|
63
|
+
let logMock: (message?: unknown, ...optionalParams: Array<unknown>) => void;
|
|
131
64
|
|
|
132
65
|
beforeEach(() => {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
66
|
+
logs = [];
|
|
67
|
+
exitCalled = false;
|
|
68
|
+
logMock = (message?: unknown, ...optionalParams: Array<unknown>) => {
|
|
69
|
+
const parts = [message, ...optionalParams].filter(
|
|
70
|
+
(part) => typeof part !== "undefined",
|
|
71
|
+
);
|
|
72
|
+
logs.push(parts.map((part) => String(part)).join(" "));
|
|
73
|
+
};
|
|
74
|
+
exitMock = () => {
|
|
75
|
+
exitCalled = true;
|
|
76
|
+
throw new Error("exit called");
|
|
77
|
+
};
|
|
139
78
|
});
|
|
140
79
|
|
|
141
80
|
it("displays sockethub version", () => {
|
|
142
81
|
const platforms = new Map();
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
82
|
+
expect(() =>
|
|
83
|
+
printSettingsInfo("5.0.0-alpha.4", platforms, {
|
|
84
|
+
log: logMock,
|
|
85
|
+
exit: exitMock,
|
|
86
|
+
}),
|
|
87
|
+
).toThrow("exit called");
|
|
88
|
+
|
|
89
|
+
expect(logs.join("\n")).toMatch(/5\.0\.0-alpha\.4/);
|
|
147
90
|
});
|
|
148
91
|
|
|
149
92
|
it("displays executable path", () => {
|
|
150
93
|
const platforms = new Map();
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
94
|
+
expect(() =>
|
|
95
|
+
printSettingsInfo("5.0.0", platforms, {
|
|
96
|
+
log: logMock,
|
|
97
|
+
exit: exitMock,
|
|
98
|
+
}),
|
|
99
|
+
).toThrow("exit called");
|
|
100
|
+
|
|
101
|
+
const output = logs.join("\n");
|
|
102
|
+
expect(output).toMatch(/executable:/);
|
|
103
|
+
expect(output).toMatch(/sockethub|init/);
|
|
155
104
|
});
|
|
156
105
|
|
|
157
106
|
it("displays platform information with colors", () => {
|
|
@@ -166,31 +115,44 @@ describe("printSettingsInfo", () => {
|
|
|
166
115
|
types: ["echo", "greet"],
|
|
167
116
|
config: {},
|
|
168
117
|
schemas: {
|
|
118
|
+
contextUrl:
|
|
119
|
+
"https://sockethub.org/ns/context/platform/dummy/v1.jsonld",
|
|
120
|
+
contextVersion: "1",
|
|
121
|
+
schemaVersion: "1",
|
|
169
122
|
credentials: {},
|
|
170
123
|
messages: {},
|
|
171
124
|
},
|
|
125
|
+
contextUrl:
|
|
126
|
+
"https://sockethub.org/ns/context/platform/dummy/v1.jsonld",
|
|
127
|
+
contextVersion: "1",
|
|
128
|
+
schemaVersion: "1",
|
|
172
129
|
},
|
|
173
130
|
],
|
|
174
131
|
]);
|
|
175
132
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
133
|
+
expect(() =>
|
|
134
|
+
printSettingsInfo("5.0.0", platforms, {
|
|
135
|
+
log: logMock,
|
|
136
|
+
exit: exitMock,
|
|
137
|
+
}),
|
|
138
|
+
).toThrow("exit called");
|
|
139
|
+
|
|
140
|
+
const output = logs.join("\n");
|
|
141
|
+
expect(output).toMatch(/platform-dummy/);
|
|
142
|
+
expect(output).toMatch(/1\.0\.0/);
|
|
143
|
+
expect(output).toMatch(/path.*dummy/);
|
|
187
144
|
});
|
|
188
145
|
|
|
189
146
|
it("calls process.exit after printing", () => {
|
|
190
147
|
const platforms = new Map();
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
148
|
+
expect(() =>
|
|
149
|
+
printSettingsInfo("5.0.0", platforms, {
|
|
150
|
+
log: logMock,
|
|
151
|
+
exit: exitMock,
|
|
152
|
+
}),
|
|
153
|
+
).toThrow("exit called");
|
|
154
|
+
|
|
155
|
+
expect(exitCalled).toBeTrue();
|
|
194
156
|
});
|
|
195
157
|
|
|
196
158
|
it("strips colors in non-TTY environment", () => {
|
|
@@ -199,11 +161,13 @@ describe("printSettingsInfo", () => {
|
|
|
199
161
|
process.env.NO_COLOR = "1";
|
|
200
162
|
|
|
201
163
|
const platforms = new Map();
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
164
|
+
expect(() =>
|
|
165
|
+
printSettingsInfo("5.0.0", platforms, {
|
|
166
|
+
log: logMock,
|
|
167
|
+
exit: exitMock,
|
|
168
|
+
}),
|
|
169
|
+
).toThrow("exit called");
|
|
170
|
+
const output = logs.join("\n");
|
|
207
171
|
expect(output).not.toMatch(/\x1b\[/); // No ANSI escape codes
|
|
208
172
|
|
|
209
173
|
process.env.NO_COLOR = oldNoColor;
|
package/src/bootstrap/init.ts
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
|
-
import chalk from "chalk";
|
|
3
|
-
|
|
4
2
|
import { type RedisConfig, redisCheck } from "@sockethub/data-layer";
|
|
5
|
-
|
|
6
3
|
import { createLogger } from "@sockethub/logger";
|
|
7
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
addPlatformContext,
|
|
6
|
+
addPlatformSchema,
|
|
7
|
+
InternalObjectTypesList,
|
|
8
|
+
setValidationErrorOptions,
|
|
9
|
+
} from "@sockethub/schemas";
|
|
10
|
+
import chalk from "chalk";
|
|
8
11
|
import config from "../config.js";
|
|
9
12
|
import loadPlatforms, {
|
|
10
13
|
type PlatformMap,
|
|
14
|
+
type PlatformSchemaRegistry,
|
|
11
15
|
type PlatformStruct,
|
|
12
16
|
} from "./load-platforms.js";
|
|
13
17
|
|
|
@@ -18,6 +22,11 @@ export interface IInitObject {
|
|
|
18
22
|
platforms: PlatformMap;
|
|
19
23
|
}
|
|
20
24
|
|
|
25
|
+
interface PrintSettingsInfoOptions {
|
|
26
|
+
log?: (message?: unknown, ...optionalParams: Array<unknown>) => void;
|
|
27
|
+
exit?: (code?: number) => unknown;
|
|
28
|
+
}
|
|
29
|
+
|
|
21
30
|
let init: IInitObject;
|
|
22
31
|
|
|
23
32
|
function getExecutablePath(): string {
|
|
@@ -32,51 +41,52 @@ function getExecutablePath(): string {
|
|
|
32
41
|
export function printSettingsInfo(
|
|
33
42
|
version: string,
|
|
34
43
|
platforms: Map<string, PlatformStruct>,
|
|
44
|
+
options: PrintSettingsInfoOptions = {},
|
|
35
45
|
) {
|
|
46
|
+
const logFn = options.log ?? console.log;
|
|
47
|
+
const exitFn = options.exit ?? process.exit;
|
|
36
48
|
const execPath = getExecutablePath();
|
|
37
49
|
|
|
38
|
-
|
|
39
|
-
|
|
50
|
+
logFn(`${chalk.cyan("sockethub")} ${version}`);
|
|
51
|
+
logFn(`${chalk.cyan("executable:")} ${execPath}`);
|
|
40
52
|
|
|
41
53
|
const wsUrl = `ws://${config.get("sockethub:host")}:${config.get("sockethub:port")}${config.get("sockethub:path")}`;
|
|
42
|
-
|
|
54
|
+
logFn(`${chalk.cyan("websocket:")} ${chalk.blue(wsUrl)}`);
|
|
43
55
|
|
|
44
56
|
const examplesUrl = `http://${config.get("public:host")}:${config.get(
|
|
45
57
|
"public:port",
|
|
46
58
|
)}${config.get("public:path")}`;
|
|
47
|
-
|
|
59
|
+
logFn(
|
|
48
60
|
`${chalk.cyan("examples:")} ${config.get("examples") ? chalk.blue(examplesUrl) : "disabled"}`,
|
|
49
61
|
);
|
|
50
62
|
|
|
51
|
-
|
|
52
|
-
`${chalk.cyan("redis URL:")} ${chalk.blue(config.get("redis:url"))}`,
|
|
53
|
-
);
|
|
63
|
+
logFn(`${chalk.cyan("redis URL:")} ${chalk.blue(config.get("redis:url"))}`);
|
|
54
64
|
|
|
55
|
-
|
|
65
|
+
logFn(
|
|
56
66
|
`${chalk.cyan("platforms:")} ${Array.from(platforms.keys()).join(", ")}`,
|
|
57
67
|
);
|
|
58
68
|
|
|
59
69
|
if (platforms.size > 0) {
|
|
60
70
|
for (const platform of platforms.values()) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
71
|
+
logFn();
|
|
72
|
+
logFn(chalk.green(`- ${platform.moduleName}`));
|
|
73
|
+
logFn(` ${chalk.dim("version:")} ${platform.version}`);
|
|
74
|
+
logFn(
|
|
65
75
|
` ${chalk.dim("AS types:")} ${platform.types.map((t) => chalk.yellow(t)).join(", ")}`,
|
|
66
76
|
);
|
|
67
77
|
if (platform.modulePath) {
|
|
68
|
-
|
|
78
|
+
logFn(` ${chalk.dim("path:")} ${platform.modulePath}`);
|
|
69
79
|
}
|
|
70
80
|
}
|
|
71
81
|
}
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
logFn();
|
|
83
|
+
exitFn();
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
let initCalled = false;
|
|
77
87
|
let initWaitCount = 0;
|
|
78
|
-
let cancelWait:
|
|
79
|
-
const resolveQueue = [];
|
|
88
|
+
let cancelWait: NodeJS.Timeout | undefined;
|
|
89
|
+
const resolveQueue: Array<(init: IInitObject) => void> = [];
|
|
80
90
|
|
|
81
91
|
export default async function getInitObject(
|
|
82
92
|
initFunc: () => Promise<IInitObject> = __loadInit,
|
|
@@ -108,6 +118,9 @@ export default async function getInitObject(
|
|
|
108
118
|
if (init) {
|
|
109
119
|
resolve(init);
|
|
110
120
|
} else {
|
|
121
|
+
setValidationErrorOptions({
|
|
122
|
+
excludeTypes: InternalObjectTypesList,
|
|
123
|
+
});
|
|
111
124
|
initFunc()
|
|
112
125
|
.then((_init) => {
|
|
113
126
|
init = _init;
|
|
@@ -122,12 +135,17 @@ export default async function getInitObject(
|
|
|
122
135
|
}
|
|
123
136
|
|
|
124
137
|
export async function registerPlatforms(initObj: IInitObject): Promise<void> {
|
|
125
|
-
for (const [
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
138
|
+
for (const [_platformId, platform] of initObj.platforms) {
|
|
139
|
+
const schemas: PlatformSchemaRegistry = platform.schemas;
|
|
140
|
+
addPlatformContext(platform.id, schemas.contextUrl);
|
|
141
|
+
if (schemas.credentials !== undefined) {
|
|
142
|
+
addPlatformSchema(
|
|
143
|
+
schemas.credentials,
|
|
144
|
+
`${platform.id}/credentials`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
if (schemas.messages !== undefined) {
|
|
148
|
+
addPlatformSchema(schemas.messages, `${platform.id}/messages`);
|
|
131
149
|
}
|
|
132
150
|
}
|
|
133
151
|
}
|
|
@@ -13,10 +13,10 @@ import { createLogger } from "@sockethub/logger";
|
|
|
13
13
|
import {
|
|
14
14
|
type PlatformConfig,
|
|
15
15
|
type PlatformInterface,
|
|
16
|
-
type PlatformSchemaStruct,
|
|
17
16
|
type PlatformSession,
|
|
18
17
|
validatePlatformSchema,
|
|
19
18
|
} from "@sockethub/schemas";
|
|
19
|
+
import type { Schema } from "ajv";
|
|
20
20
|
|
|
21
21
|
const log = createLogger("server:bootstrap:platforms");
|
|
22
22
|
|
|
@@ -25,13 +25,26 @@ export type PlatformStruct = {
|
|
|
25
25
|
moduleName: string;
|
|
26
26
|
modulePath?: string;
|
|
27
27
|
config: PlatformConfig;
|
|
28
|
-
schemas:
|
|
28
|
+
schemas: PlatformSchemaRegistry;
|
|
29
29
|
version: string;
|
|
30
|
+
contextUrl: string;
|
|
31
|
+
contextVersion: string;
|
|
32
|
+
schemaVersion: string;
|
|
30
33
|
types: Array<string>;
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
export type PlatformMap = Map<string, PlatformStruct>;
|
|
34
37
|
|
|
38
|
+
export type PlatformSchemaRegistry = {
|
|
39
|
+
name: string;
|
|
40
|
+
version: string;
|
|
41
|
+
contextUrl: string;
|
|
42
|
+
contextVersion: string;
|
|
43
|
+
schemaVersion: string;
|
|
44
|
+
credentials?: Schema | boolean;
|
|
45
|
+
messages?: Schema | boolean;
|
|
46
|
+
};
|
|
47
|
+
|
|
35
48
|
const dummySession: PlatformSession = {
|
|
36
49
|
log: createLogger("platform:dummy"),
|
|
37
50
|
sendToClient: () => {},
|
|
@@ -40,7 +53,7 @@ const dummySession: PlatformSession = {
|
|
|
40
53
|
|
|
41
54
|
// if the platform schema lists valid types it implements (essentially methods/verbs for
|
|
42
55
|
// Sockethub to call) then add it to the supported types list.
|
|
43
|
-
function platformListsSupportedTypes(p): boolean {
|
|
56
|
+
function platformListsSupportedTypes(p: PlatformInterface): boolean {
|
|
44
57
|
return (
|
|
45
58
|
p.schema.messages.properties?.type?.enum &&
|
|
46
59
|
p.schema.messages.properties.type.enum.length > 0
|
|
@@ -70,13 +83,23 @@ function resolveModulePath(platformName: string): string | undefined {
|
|
|
70
83
|
return dirname(filePath);
|
|
71
84
|
} catch (err) {
|
|
72
85
|
log.warn(
|
|
73
|
-
`failed to resolve module path for ${platformName}: ${
|
|
86
|
+
`failed to resolve module path for ${platformName}: ${
|
|
87
|
+
err instanceof Error ? err.message : String(err)
|
|
88
|
+
}`,
|
|
74
89
|
);
|
|
75
90
|
return undefined;
|
|
76
91
|
}
|
|
77
92
|
}
|
|
78
93
|
|
|
79
|
-
|
|
94
|
+
type PlatformConstructor = new (...args: unknown[]) => PlatformInterface;
|
|
95
|
+
type InjectRequire = (
|
|
96
|
+
moduleName: string,
|
|
97
|
+
) => Promise<PlatformConstructor> | PlatformConstructor;
|
|
98
|
+
|
|
99
|
+
async function loadPlatform(
|
|
100
|
+
platformName: string,
|
|
101
|
+
injectRequire?: InjectRequire,
|
|
102
|
+
) {
|
|
80
103
|
log.debug(`loading ${platformName}`);
|
|
81
104
|
let p: PlatformInterface;
|
|
82
105
|
if (injectRequire) {
|
|
@@ -101,11 +124,11 @@ async function loadPlatform(platformName: string, injectRequire) {
|
|
|
101
124
|
|
|
102
125
|
export default async function loadPlatforms(
|
|
103
126
|
platformsList: Array<string>,
|
|
104
|
-
injectRequire
|
|
127
|
+
injectRequire?: InjectRequire,
|
|
105
128
|
): Promise<PlatformMap> {
|
|
106
129
|
log.debug(`platforms to load: ${platformsList}`);
|
|
107
130
|
// load platforms from config.platforms
|
|
108
|
-
const platforms = new Map();
|
|
131
|
+
const platforms = new Map<string, PlatformStruct>();
|
|
109
132
|
|
|
110
133
|
if (platformsList.length <= 0) {
|
|
111
134
|
throw new Error(
|
|
@@ -115,7 +138,7 @@ export default async function loadPlatforms(
|
|
|
115
138
|
|
|
116
139
|
for (const platformName of platformsList) {
|
|
117
140
|
const p = await loadPlatform(platformName, injectRequire);
|
|
118
|
-
let types = [];
|
|
141
|
+
let types: Array<string> = [];
|
|
119
142
|
|
|
120
143
|
if (p.schema.credentials) {
|
|
121
144
|
// register the platforms credentials schema
|
|
@@ -139,10 +162,18 @@ export default async function loadPlatforms(
|
|
|
139
162
|
modulePath: modulePath,
|
|
140
163
|
config: p.config,
|
|
141
164
|
schemas: {
|
|
165
|
+
name: p.schema.name,
|
|
166
|
+
version: p.schema.version,
|
|
167
|
+
contextUrl: p.schema.contextUrl,
|
|
168
|
+
contextVersion: p.schema.contextVersion,
|
|
169
|
+
schemaVersion: p.schema.schemaVersion,
|
|
142
170
|
credentials: p.schema.credentials || {},
|
|
143
171
|
messages: p.schema.messages || {},
|
|
144
172
|
},
|
|
145
173
|
version: p.schema.version,
|
|
174
|
+
contextUrl: p.schema.contextUrl,
|
|
175
|
+
contextVersion: p.schema.contextVersion,
|
|
176
|
+
schemaVersion: p.schema.schemaVersion,
|
|
146
177
|
types: types,
|
|
147
178
|
});
|
|
148
179
|
log.info(`loaded platform ${p.schema.name} v${p.schema.version}`);
|
package/src/config.ts
CHANGED
|
@@ -2,7 +2,7 @@ import fs from "node:fs";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import nconf from "nconf";
|
|
4
4
|
|
|
5
|
-
import { type Logger
|
|
5
|
+
import { createWinstonLogger, type Logger } from "./logger-core.js";
|
|
6
6
|
import { __dirname } from "./util.js";
|
|
7
7
|
|
|
8
8
|
const data = JSON.parse(
|
|
@@ -109,6 +109,17 @@ export class Config {
|
|
|
109
109
|
"logging:file",
|
|
110
110
|
process.env.LOG_FILE || nconf.get("logging:file"),
|
|
111
111
|
);
|
|
112
|
+
|
|
113
|
+
nconf.set(
|
|
114
|
+
"platformHeartbeat:intervalMs",
|
|
115
|
+
process.env.SOCKETHUB_PLATFORM_HEARTBEAT_INTERVAL_MS ||
|
|
116
|
+
nconf.get("platformHeartbeat:intervalMs"),
|
|
117
|
+
);
|
|
118
|
+
nconf.set(
|
|
119
|
+
"platformHeartbeat:timeoutMs",
|
|
120
|
+
process.env.SOCKETHUB_PLATFORM_HEARTBEAT_TIMEOUT_MS ||
|
|
121
|
+
nconf.get("platformHeartbeat:timeoutMs"),
|
|
122
|
+
);
|
|
112
123
|
}
|
|
113
124
|
get = (key: string) => nconf.get(key);
|
|
114
125
|
}
|
package/src/defaults.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import config from "./config";
|
|
|
4
4
|
import Sockethub from "./sockethub";
|
|
5
5
|
|
|
6
6
|
let sentry: { readonly reportError: (err: Error) => void } = {
|
|
7
|
-
reportError: (
|
|
7
|
+
reportError: (_err: Error) => {},
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
export async function server() {
|
|
@@ -34,8 +34,9 @@ export async function server() {
|
|
|
34
34
|
try {
|
|
35
35
|
sockethub = new Sockethub();
|
|
36
36
|
} catch (err) {
|
|
37
|
-
|
|
38
|
-
|
|
37
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
38
|
+
sentry.reportError(error);
|
|
39
|
+
console.error(error);
|
|
39
40
|
process.exit(1);
|
|
40
41
|
}
|
|
41
42
|
|
|
@@ -48,12 +49,12 @@ export async function server() {
|
|
|
48
49
|
process.exit(1);
|
|
49
50
|
});
|
|
50
51
|
|
|
51
|
-
process.once("unhandledRejection", (err:
|
|
52
|
+
process.once("unhandledRejection", (err: unknown) => {
|
|
52
53
|
console.error(
|
|
53
54
|
`${(new Date()).toUTCString()} UNHANDLED REJECTION\n`,
|
|
54
55
|
err,
|
|
55
56
|
);
|
|
56
|
-
sentry.reportError(err);
|
|
57
|
+
sentry.reportError(err instanceof Error ? err : new Error(String(err)));
|
|
57
58
|
process.exit(1);
|
|
58
59
|
});
|
|
59
60
|
|
|
@@ -76,8 +77,9 @@ export async function server() {
|
|
|
76
77
|
try {
|
|
77
78
|
await sockethub.boot();
|
|
78
79
|
} catch (err) {
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
81
|
+
sentry.reportError(error);
|
|
82
|
+
console.error(error);
|
|
81
83
|
process.exit(1);
|
|
82
84
|
}
|
|
83
85
|
}
|
package/src/janitor.ts
CHANGED
|
@@ -44,7 +44,9 @@ export class Janitor {
|
|
|
44
44
|
platformInstance: PlatformInstance,
|
|
45
45
|
sessionId: string,
|
|
46
46
|
): void {
|
|
47
|
-
for (const key
|
|
47
|
+
for (const key of Object.keys(
|
|
48
|
+
platformInstance.sessionCallbacks,
|
|
49
|
+
) as Array<"close" | "message">) {
|
|
48
50
|
platformInstance.process.removeListener(
|
|
49
51
|
key,
|
|
50
52
|
platformInstance.sessionCallbacks[key].get(sessionId),
|