@sockethub/server 5.0.0-alpha.4 → 5.0.0-alpha.6

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.
Files changed (105) hide show
  1. package/README.md +54 -60
  2. package/bin/sockethub +4 -3
  3. package/package.json +42 -54
  4. package/res/socket.io.js +4908 -0
  5. package/res/sockethub-client.js +602 -0
  6. package/res/sockethub-client.min.js +19 -0
  7. package/sockethub.config.example.json +2 -3
  8. package/src/bootstrap/init.d.ts +16 -13
  9. package/src/bootstrap/init.test.ts +211 -0
  10. package/src/bootstrap/init.ts +152 -76
  11. package/src/bootstrap/load-platforms.ts +151 -0
  12. package/src/config.test.ts +27 -22
  13. package/src/config.ts +82 -86
  14. package/src/defaults.json +24 -16
  15. package/src/index.ts +61 -22
  16. package/src/janitor.test.ts +191 -169
  17. package/src/janitor.ts +141 -118
  18. package/src/listener.ts +148 -58
  19. package/src/middleware/create-activity-object.test.ts +28 -8
  20. package/src/middleware/create-activity-object.ts +16 -10
  21. package/src/middleware/expand-activity-stream.test.data.ts +331 -345
  22. package/src/middleware/expand-activity-stream.test.ts +65 -66
  23. package/src/middleware/expand-activity-stream.ts +26 -21
  24. package/src/middleware/store-credentials.test.ts +74 -60
  25. package/src/middleware/store-credentials.ts +14 -8
  26. package/src/middleware/validate.test.data.ts +240 -242
  27. package/src/middleware/validate.test.ts +39 -78
  28. package/src/middleware/validate.ts +62 -36
  29. package/src/middleware.test.ts +168 -138
  30. package/src/middleware.ts +57 -55
  31. package/src/platform-instance.test.ts +508 -214
  32. package/src/platform-instance.ts +324 -231
  33. package/src/platform.test.ts +375 -0
  34. package/src/platform.ts +306 -117
  35. package/src/process-manager.ts +75 -51
  36. package/src/routes.test.ts +43 -89
  37. package/src/routes.ts +40 -78
  38. package/src/sentry.test.ts +106 -0
  39. package/src/sentry.ts +19 -0
  40. package/src/sockethub.ts +190 -129
  41. package/src/util.ts +5 -0
  42. package/coverage/tmp/coverage-39338-1663949520416-0.json +0 -1
  43. package/dist/bootstrap/init.d.ts +0 -18
  44. package/dist/bootstrap/init.js +0 -64
  45. package/dist/bootstrap/init.js.map +0 -1
  46. package/dist/bootstrap/platforms.js +0 -75
  47. package/dist/config.d.ts +0 -12
  48. package/dist/config.js +0 -107
  49. package/dist/config.js.map +0 -1
  50. package/dist/defaults.json +0 -28
  51. package/dist/index.d.ts +0 -1
  52. package/dist/index.js +0 -29
  53. package/dist/index.js.map +0 -1
  54. package/dist/janitor.d.ts +0 -30
  55. package/dist/janitor.js +0 -120
  56. package/dist/janitor.js.map +0 -1
  57. package/dist/listener.d.ts +0 -31
  58. package/dist/listener.js +0 -94
  59. package/dist/listener.js.map +0 -1
  60. package/dist/middleware/create-activity-object.d.ts +0 -8
  61. package/dist/middleware/create-activity-object.js +0 -19
  62. package/dist/middleware/create-activity-object.js.map +0 -1
  63. package/dist/middleware/expand-activity-stream.d.ts +0 -3
  64. package/dist/middleware/expand-activity-stream.js +0 -36
  65. package/dist/middleware/expand-activity-stream.js.map +0 -1
  66. package/dist/middleware/expand-activity-stream.test.data.d.ts +0 -480
  67. package/dist/middleware/expand-activity-stream.test.data.js +0 -360
  68. package/dist/middleware/expand-activity-stream.test.data.js.map +0 -1
  69. package/dist/middleware/store-credentials.d.ts +0 -3
  70. package/dist/middleware/store-credentials.js +0 -9
  71. package/dist/middleware/store-credentials.js.map +0 -1
  72. package/dist/middleware/validate.d.ts +0 -2
  73. package/dist/middleware/validate.js +0 -56
  74. package/dist/middleware/validate.js.map +0 -1
  75. package/dist/middleware/validate.test.data.d.ts +0 -532
  76. package/dist/middleware/validate.test.data.js +0 -263
  77. package/dist/middleware/validate.test.data.js.map +0 -1
  78. package/dist/middleware.d.ts +0 -21
  79. package/dist/middleware.js +0 -56
  80. package/dist/middleware.js.map +0 -1
  81. package/dist/platform-instance.d.ts +0 -78
  82. package/dist/platform-instance.js +0 -226
  83. package/dist/platform-instance.js.map +0 -1
  84. package/dist/platform.d.ts +0 -6
  85. package/dist/platform.js +0 -176
  86. package/dist/platform.js.map +0 -1
  87. package/dist/process-manager.d.ts +0 -11
  88. package/dist/process-manager.js +0 -82
  89. package/dist/process-manager.js.map +0 -1
  90. package/dist/routes.d.ts +0 -13
  91. package/dist/routes.js +0 -83
  92. package/dist/routes.js.map +0 -1
  93. package/dist/sockethub.d.ts +0 -18
  94. package/dist/sockethub.js +0 -112
  95. package/dist/sockethub.js.map +0 -1
  96. package/src/bootstrap/platforms.js +0 -75
  97. package/test/init-suite.js +0 -41
  98. package/test/sockethub-suite.js +0 -25
  99. package/tsconfig.json +0 -18
  100. package/views/examples/dummy.ejs +0 -95
  101. package/views/examples/feeds.ejs +0 -90
  102. package/views/examples/irc.ejs +0 -239
  103. package/views/examples/shared.js +0 -72
  104. package/views/examples/xmpp.ejs +0 -217
  105. package/views/index.ejs +0 -17
package/src/janitor.ts CHANGED
@@ -1,133 +1,156 @@
1
- import debug from 'debug';
2
-
3
- import PlatformInstance, { platformInstances } from './platform-instance';
4
- import listener, { SocketInstance } from "./listener";
5
-
6
- const rmLog = debug('sockethub:server:janitor');
7
-
8
- class Janitor {
9
- cycleInterval = 15000;
10
- cycleCount = 0; // a counter for each cycleInterval
11
- reportCount = 0; // number of times a report is printed
12
- protected stopTriggered = false;
13
- protected sockets: Array<SocketInstance>;
14
- private cycleRunning = false;
15
-
16
- /**
17
- * Every TICK the `Janitor` will compare existing platform instances with `socket.ids`
18
- * (aka. `sessionId`). If all of the `sessionIds` associated with a `platformInstance` have
19
- * no corresponding `socket.id` (from the `http.io` `socket.io` instance), then the
20
- * `platformInstance` will first be flagged, if after the next `cycleInterval` the same
21
- * state is determined, the platform will be destroyed (this allows for page
22
- * refreshes not destroying platform instances)
23
- */
24
- start(): void {
25
- rmLog('initializing');
26
- this.clean().then(() => {
27
- rmLog('cleaning cycle started');
28
- });
29
- }
30
-
31
- async stop(): Promise<void> {
32
- this.stopTriggered = true;
33
- rmLog('stopping, terminating all sessions');
34
- for (const platformInstance of platformInstances.values()) {
35
- this.removeStaleSocketSessions(platformInstance);
36
- await this.removeStalePlatformInstance(platformInstance);
37
- await platformInstance.shutdown();
1
+ import debug from "debug";
2
+
3
+ import listener, { type SocketInstance } from "./listener.js";
4
+ import type PlatformInstance from "./platform-instance.js";
5
+ import { platformInstances } from "./platform-instance.js";
6
+
7
+ const rmLog = debug("sockethub:server:janitor");
8
+
9
+ export class Janitor {
10
+ cycleInterval = 15000;
11
+ cycleCount = 0; // a counter for each cycleInterval
12
+ reportCount = 0; // number of times a report is printed
13
+ protected stopTriggered = false;
14
+ protected sockets: Array<SocketInstance>;
15
+ private cycleRunning = false;
16
+
17
+ /**
18
+ * Every TICK the `Janitor` will compare existing platform instances with `socket.ids`
19
+ * (aka. `sessionId`). If all the `sessionIds` associated with a `platformInstance` have
20
+ * no corresponding `socket.id` (from the `http.io` `socket.io` instance), then the
21
+ * `platformInstance` will first be flagged, if after the next `cycleInterval` the same
22
+ * state is determined, the platform will be destroyed (this allows for page
23
+ * refreshes not destroying platform instances)
24
+ */
25
+ start(): void {
26
+ rmLog("initializing");
27
+ this.clean().then(() => {
28
+ rmLog("cleaning cycle started");
29
+ });
38
30
  }
39
- }
40
31
 
41
- private removeSessionCallbacks(platformInstance: PlatformInstance, sessionId: string): void {
42
- for (const key in platformInstance.sessionCallbacks) {
43
- platformInstance.process.removeListener(
44
- key, platformInstance.sessionCallbacks[key].get(sessionId));
45
- platformInstance.sessionCallbacks[key].delete(sessionId);
32
+ async stop(): Promise<void> {
33
+ this.stopTriggered = true;
34
+ rmLog("stopping, terminating all sessions");
35
+ for (const platformInstance of platformInstances.values()) {
36
+ this.removeStaleSocketSessions(platformInstance);
37
+ await this.removeStalePlatformInstance(platformInstance);
38
+ await platformInstance.shutdown();
39
+ }
46
40
  }
47
- }
48
-
49
- private removeStaleSocketSessions(
50
- platformInstance: PlatformInstance
51
- ): void {
52
- for (const sessionId of platformInstance.sessions.values()) {
53
- if ((this.stopTriggered) || (!this.socketExists(sessionId))) {
54
- this.removeStaleSocketSession(platformInstance, sessionId);
55
- }
41
+
42
+ private removeSessionCallbacks(
43
+ platformInstance: PlatformInstance,
44
+ sessionId: string,
45
+ ): void {
46
+ for (const key in platformInstance.sessionCallbacks) {
47
+ platformInstance.process.removeListener(
48
+ key,
49
+ platformInstance.sessionCallbacks[key].get(sessionId),
50
+ );
51
+ platformInstance.sessionCallbacks[key].delete(sessionId);
52
+ }
56
53
  }
57
- }
58
-
59
- private removeStaleSocketSession(platformInstance: PlatformInstance, sessionId: string) {
60
- rmLog(
61
- `removing ${!this.stopTriggered ? 'stale ' : ''}socket session reference ${sessionId}
62
- in platform instance ${platformInstance.id}`
63
- );
64
- platformInstance.sessions.delete(sessionId);
65
- this.removeSessionCallbacks(platformInstance, sessionId);
66
- }
67
-
68
- private async removeStalePlatformInstance(platformInstance: PlatformInstance): Promise<void> {
69
- if ((platformInstance.flaggedForTermination) || (this.stopTriggered)) {
70
- rmLog(`terminating platform instance ${platformInstance.id}`);
71
- await platformInstance.shutdown(); // terminate
72
- } else {
73
- rmLog(`flagging for termination platform instance ${platformInstance.id} ` +
74
- `(no registered sessions found)`);
75
- platformInstance.flaggedForTermination = true;
54
+
55
+ private removeStaleSocketSessions(
56
+ platformInstance: PlatformInstance,
57
+ ): void {
58
+ for (const sessionId of platformInstance.sessions.values()) {
59
+ if (this.stopTriggered || !this.socketExists(sessionId)) {
60
+ this.removeStaleSocketSession(platformInstance, sessionId);
61
+ }
62
+ }
76
63
  }
77
- }
78
64
 
79
- private socketExists(sessionId: string) {
80
- for (const socket of this.sockets) {
81
- if (socket.id === sessionId) {
82
- return true;
83
- }
65
+ private removeStaleSocketSession(
66
+ platformInstance: PlatformInstance,
67
+ sessionId: string,
68
+ ) {
69
+ rmLog(
70
+ `removing ${
71
+ !this.stopTriggered ? "stale " : ""
72
+ }socket session reference ${sessionId}
73
+ in platform instance ${platformInstance.id}`,
74
+ );
75
+ platformInstance.sessions.delete(sessionId);
76
+ this.removeSessionCallbacks(platformInstance, sessionId);
84
77
  }
85
- return false;
86
- }
87
-
88
- private async delay(ms): Promise<void> {
89
- return await new Promise(resolve => setTimeout(resolve, ms));
90
- }
91
-
92
- private async getSockets(): Promise<Array<SocketInstance>> {
93
- return await listener.io.fetchSockets();
94
- }
95
-
96
- private async performStaleCheck(platformInstance: PlatformInstance) {
97
- this.removeStaleSocketSessions(platformInstance);
98
- // Static platforms are for global use, not tied to a unique to session / eg. credentials)
99
- if (!platformInstance.global) {
100
- if ((!platformInstance.initialized) || (platformInstance.sessions.size === 0)) {
101
- // either the platform failed to initialize, or there are no more sessions linked to it
102
- await this.removeStalePlatformInstance(platformInstance);
103
- }
78
+
79
+ private async removeStalePlatformInstance(
80
+ platformInstance: PlatformInstance,
81
+ ): Promise<void> {
82
+ if (platformInstance.flaggedForTermination || this.stopTriggered) {
83
+ rmLog(`terminating platform instance ${platformInstance.id}`);
84
+ await platformInstance.shutdown(); // terminate
85
+ } else {
86
+ rmLog(
87
+ `flagging for termination platform instance ${platformInstance.id} (no registered sessions found)`,
88
+ );
89
+ platformInstance.flaggedForTermination = true;
90
+ }
104
91
  }
105
- }
106
-
107
- private async clean(): Promise<void> {
108
- if (this.stopTriggered) {
109
- this.cycleRunning = false;
110
- return;
111
- } else if (this.cycleRunning) {
112
- throw new Error('janitor cleanup cycle called while already running');
92
+
93
+ private socketExists(sessionId: string) {
94
+ for (const socket of this.sockets) {
95
+ if (socket.id === sessionId) {
96
+ return true;
97
+ }
98
+ }
99
+ return false;
113
100
  }
114
- this.cycleRunning = true;
115
- this.cycleCount++;
116
- this.sockets = await this.getSockets();
117
-
118
- if (!(this.cycleCount % 4)) {
119
- this.reportCount++;
120
- rmLog(
121
- `socket sessions: ${this.sockets.length} platform instances: ${platformInstances.size}`);
101
+
102
+ private async delay(ms: number): Promise<void> {
103
+ return await new Promise((resolve) => setTimeout(resolve, ms));
104
+ }
105
+
106
+ private async getSockets(): Promise<Array<SocketInstance>> {
107
+ return listener.io.fetchSockets();
108
+ }
109
+
110
+ private async performStaleCheck(platformInstance: PlatformInstance) {
111
+ this.removeStaleSocketSessions(platformInstance);
112
+ // Static platforms are for global use, not tied to a unique to session
113
+ // (e.g. a stateful platform where credentials are supplied)
114
+ if (!platformInstance.global) {
115
+ if (
116
+ (platformInstance.config.persist &&
117
+ !platformInstance.config.initialized) ||
118
+ platformInstance.sessions.size === 0
119
+ ) {
120
+ // either the platform failed to initialize, or there are no more sessions linked to it
121
+ await this.removeStalePlatformInstance(platformInstance);
122
+ }
123
+ }
122
124
  }
123
125
 
124
- for (const platformInstance of platformInstances.values()) {
125
- await this.performStaleCheck(platformInstance);
126
+ private async clean(): Promise<void> {
127
+ if (this.stopTriggered) {
128
+ this.cycleRunning = false;
129
+ return;
130
+ }
131
+ if (this.cycleRunning) {
132
+ throw new Error(
133
+ "janitor cleanup cycle called while already running",
134
+ );
135
+ }
136
+ this.cycleRunning = true;
137
+ this.cycleCount++;
138
+ this.sockets = await this.getSockets();
139
+
140
+ if (!(this.cycleCount % 4)) {
141
+ this.reportCount++;
142
+ rmLog(
143
+ `socket sessions: ${this.sockets.length} platform instances: ${platformInstances.size}`,
144
+ );
145
+ }
146
+
147
+ for (const platformInstance of platformInstances.values()) {
148
+ await this.performStaleCheck(platformInstance);
149
+ }
150
+ this.cycleRunning = false;
151
+ await this.delay(this.cycleInterval);
152
+ return this.clean();
126
153
  }
127
- this.cycleRunning = false;
128
- await this.delay(this.cycleInterval);
129
- return this.clean();
130
- }
131
154
  }
132
155
 
133
156
  const janitor = new Janitor();
package/src/listener.ts CHANGED
@@ -1,13 +1,18 @@
1
- import debug from 'debug';
2
- import bodyParser from 'body-parser';
3
- import express from 'express';
4
- import * as HTTP from 'http';
5
- import { Server } from 'socket.io';
1
+ import { existsSync, writeFileSync } from "node:fs";
2
+ import * as HTTP from "node:http";
3
+ import { createRequire } from "node:module";
4
+ import path from "node:path";
5
+ import bodyParser from "body-parser";
6
+ import debug from "debug";
7
+ import express from "express";
8
+ import rateLimit from "express-rate-limit";
9
+ import { Server } from "socket.io";
6
10
 
7
- import config from './config';
8
- import routes from './routes';
11
+ import config from "./config.js";
12
+ import routes from "./routes.js";
13
+ const require = createRequire(import.meta.url);
9
14
 
10
- const log = debug('sockethub:server:listener');
15
+ const log = debug("sockethub:server:listener");
11
16
 
12
17
  /**
13
18
  * Handles the initialization and access of Sockethub resources.
@@ -17,67 +22,152 @@ const log = debug('sockethub:server:listener');
17
22
  * - Socket.io (bidirectional websocket communication)
18
23
  */
19
24
  class Listener {
20
- io: Server;
21
- http: HTTP.Server;
22
-
23
- /**
24
- * Starts the services needed for Sockethub to operate. After this command completes,
25
- * the `http` and `io` class properties will be set.
26
- */
27
- start() {
28
- // initialize express and socket.io objects
29
- const app = Listener.initExpress();
30
- this.http = new HTTP.Server(app);
31
- this.io = new Server(this.http, {
32
- path: config.get('sockethub:path') as string,
33
- cors: {
34
- origin: "*",
35
- methods: [ "GET", "POST" ]
36
- }
37
- });
38
- routes.setup(app);
39
- this.startHttp();
40
- }
41
-
42
- private startHttp() {
43
- this.http.listen(config.get('sockethub:port'), config.get('sockethub:host') as number, () => {
44
- log(`sockethub listening on ` +
45
- `${config.get('sockethub:host')}:${config.get('sockethub:port')}`);
46
- });
47
- }
48
-
49
- private static initExpress() {
50
- const app = express();
51
- // templating engines
52
- app.set('view engine', 'ejs');
53
- // use bodyParser
54
- app.use(bodyParser.urlencoded({extended: true}));
55
- app.use(bodyParser.json());
56
- return app;
57
- }
25
+ io: Server;
26
+ http: HTTP.Server;
27
+
28
+ /**
29
+ * Starts the services needed for Sockethub to operate. After this command completes,
30
+ * the `http` and `io` class properties will be set.
31
+ */
32
+ start() {
33
+ // initialize express and socket.io objects
34
+ const app = Listener.initExpress();
35
+ this.http = new HTTP.Server(app);
36
+ this.io = new Server(this.http, {
37
+ path: config.get("sockethub:path") as string,
38
+ cors: {
39
+ origin: "*",
40
+ methods: ["GET", "POST"],
41
+ },
42
+ });
43
+
44
+ routes.setup(app);
45
+
46
+ if (config.get("examples")) {
47
+ this.addExamplesRoutes(app);
48
+ }
49
+
50
+ this.startHttp();
51
+ }
52
+
53
+ /**
54
+ * Resolves the path to the examples static files from @sockethub/examples package.
55
+ * Returns null if the package is not installed.
56
+ */
57
+ private resolveExamplesPath(): string | null {
58
+ try {
59
+ const examplesPkgPath = require.resolve(
60
+ "@sockethub/examples/package.json",
61
+ );
62
+ const examplesDir = path.join(
63
+ path.dirname(examplesPkgPath),
64
+ "build",
65
+ );
66
+ if (existsSync(examplesDir)) {
67
+ log(
68
+ `examples resolved from @sockethub/examples: ${examplesDir}`,
69
+ );
70
+ return examplesDir;
71
+ }
72
+ log(
73
+ `@sockethub/examples found but build directory missing: ${examplesDir}`,
74
+ );
75
+ return null;
76
+ } catch {
77
+ return null;
78
+ }
79
+ }
80
+
81
+ private addExamplesRoutes(app) {
82
+ const examplesPath = this.resolveExamplesPath();
83
+
84
+ if (!examplesPath) {
85
+ console.error(
86
+ "\n❌ Error: --examples flag requires @sockethub/examples package\n\n" +
87
+ "The examples package is not installed. To use the examples feature, install it:\n\n" +
88
+ " bun add @sockethub/examples\n\n" +
89
+ "Or run sockethub without the --examples flag.\n",
90
+ );
91
+ process.exit(1);
92
+ }
93
+
94
+ // Set up rate limiter to prevent DoS attacks on file system access
95
+ const limiter = rateLimit({
96
+ windowMs: 1 * 60 * 1000, // 1 minute
97
+ max: 60, // max 60 requests per windowMs
98
+ standardHeaders: true,
99
+ legacyHeaders: false,
100
+ });
101
+
102
+ // Write runtime config for the examples app
103
+ writeFileSync(
104
+ path.join(examplesPath, "config.json"),
105
+ JSON.stringify({
106
+ sockethub: config.get("sockethub"),
107
+ public: config.get("public"),
108
+ }),
109
+ );
110
+
111
+ app.use(express.static(examplesPath));
112
+
113
+ const examplesIndex = path.join(examplesPath, "index.html");
114
+ app.get("*", limiter, (req, res) => {
115
+ res.sendFile(examplesIndex);
116
+ });
117
+
118
+ log(
119
+ `examples served at http://${config.get("sockethub:host")}:${config.get(
120
+ "sockethub:port",
121
+ )}`,
122
+ );
123
+ }
124
+
125
+ private startHttp() {
126
+ this.http.listen(
127
+ config.get("sockethub:port"),
128
+ config.get("sockethub:host") as number,
129
+ () => {
130
+ log(
131
+ `sockethub listening on ws://${config.get("sockethub:host")}:${config.get(
132
+ "sockethub:port",
133
+ )}`,
134
+ );
135
+ },
136
+ );
137
+ }
138
+
139
+ private static initExpress() {
140
+ const app = express();
141
+ // templating engines
142
+ app.set("view engine", "ejs");
143
+ // use bodyParser
144
+ app.use(bodyParser.urlencoded({ extended: true }));
145
+ app.use(bodyParser.json());
146
+ return app;
147
+ }
58
148
  }
59
149
 
60
150
  const listener = new Listener();
61
151
 
62
152
  interface EmitFunction {
63
- (type: string, data: unknown)
153
+ (type: string, data: unknown);
64
154
  }
65
155
 
66
156
  export interface SocketInstance {
67
- id: string;
68
- emit: EmitFunction;
157
+ id: string;
158
+ emit: EmitFunction;
69
159
  }
70
160
 
71
161
  export async function getSocket(sessionId: string): Promise<SocketInstance> {
72
- const sockets: Array<SocketInstance> = await listener.io.fetchSockets();
73
- return new Promise((resolve, reject) => {
74
- for (const socket of sockets) {
75
- if (sessionId === socket.id) {
76
- return resolve(socket);
77
- }
78
- }
79
- return reject(`unable to find socket for sessionId ${sessionId}`);
80
- });
162
+ const sockets: Array<SocketInstance> = await listener.io.fetchSockets();
163
+ return new Promise((resolve, reject) => {
164
+ for (const socket of sockets) {
165
+ if (sessionId === socket.id) {
166
+ return resolve(socket);
167
+ }
168
+ }
169
+ return reject(`unable to find socket for sessionId ${sessionId}`);
170
+ });
81
171
  }
82
172
 
83
173
  export default listener;
@@ -1,10 +1,30 @@
1
- import createActivityObject from "./create-activity-object";
1
+ import { describe, expect, it } from "bun:test";
2
+ import createActivityObject from "./create-activity-object.js";
2
3
 
3
- describe('Middleware: createActivityObject', () => {
4
- it('Calls activity.Object.create with incoming data', (done) => {
5
- // @ts-ignore
6
- createActivityObject({foo: 'bar'}, (msg) => {
7
- done();
4
+ describe("Middleware: createActivityObject", () => {
5
+ it("Calls activity.Object.create and fails with invalid property", async () => {
6
+ expect(() => {
7
+ createActivityObject({ foo: "bar" }, (o) => {
8
+ expect(o).not.toEqual({ foo: "bar" });
9
+ });
10
+ }).toThrow("ActivityStreams validation failed: the \"object\" property requires an 'id' property. Example: { id: \"user@example.com\", type: \"person\" }");
8
11
  });
9
- });
10
- });
12
+ it("Calls activity.Object.create with incoming data", async () => {
13
+ createActivityObject(
14
+ {
15
+ id: "test",
16
+ context: "foo",
17
+ type: "bar",
18
+ content: "some text",
19
+ },
20
+ (o) => {
21
+ expect(o).toEqual({
22
+ id: "test",
23
+ context: "foo",
24
+ type: "bar",
25
+ content: "some text",
26
+ });
27
+ },
28
+ );
29
+ });
30
+ });
@@ -1,16 +1,22 @@
1
- import ActivityStreams from '@sockethub/activity-streams';
2
- import config from "../config";
3
- import {IActivityStream} from "@sockethub/schemas";
4
- import {MiddlewareChainInterface} from "../middleware";
5
- const activity = ActivityStreams(config.get('activity-streams:opts'));
1
+ import { ASFactory } from "@sockethub/activity-streams";
2
+ import type { ActivityObject } from "@sockethub/schemas";
3
+
4
+ import config from "../config.js";
5
+ import type { MiddlewareChainInterface } from "../middleware.js";
6
+
7
+ const activity = ASFactory(
8
+ config.get("packageConfig:@sockethub/activity-streams"),
9
+ );
6
10
 
7
11
  /**
8
- * A simple middleware wrapper for the activity-streams Object.create method.
12
+ * A simple middleware wrapper for the activity-streams `Object.create` method.
9
13
  * @param obj
10
14
  * @param done
11
15
  */
12
- export default function createActivityObject(obj: IActivityStream,
13
- done: MiddlewareChainInterface) {
14
- activity.Object.create(obj);
15
- done(obj);
16
+ export default function createActivityObject(
17
+ obj: ActivityObject,
18
+ done: MiddlewareChainInterface,
19
+ ) {
20
+ activity.Object.create(obj);
21
+ done(obj);
16
22
  }