@furystack/websocket-api 13.1.11 → 13.1.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [13.1.12] - 2026-02-26
4
+
5
+ ### ⬆️ Dependencies
6
+
7
+ - Updated `@furystack/rest-service` dependency
8
+
3
9
  ## [13.1.11] - 2026-02-22
4
10
 
5
11
  ### ⬆️ Dependencies
@@ -7,23 +7,37 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  import { InMemoryStore, User, addStore } from '@furystack/core';
8
8
  import { getPort } from '@furystack/core/port-generator';
9
9
  import { Injectable, Injector } from '@furystack/inject';
10
+ import { getRepository } from '@furystack/repository';
10
11
  import { DefaultSession } from '@furystack/rest-service';
12
+ import { PasswordCredential, PasswordResetToken, usePasswordPolicy } from '@furystack/security';
11
13
  import { usingAsync } from '@furystack/utils';
12
14
  import { describe, expect, it } from 'vitest';
13
15
  import { WebSocket } from 'ws';
14
16
  import { useWebsockets } from './helpers.js';
15
17
  import { WebSocketApi } from './websocket-api.js';
18
+ const setupStoresAndDataSets = (injector) => {
19
+ addStore(injector, new InMemoryStore({ model: User, primaryKey: 'username' }))
20
+ .addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
21
+ .addStore(new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }))
22
+ .addStore(new InMemoryStore({ model: PasswordResetToken, primaryKey: 'token' }));
23
+ const repo = getRepository(injector);
24
+ repo.createDataSet(User, 'username');
25
+ repo.createDataSet(DefaultSession, 'sessionId');
26
+ repo.createDataSet(PasswordCredential, 'userName');
27
+ repo.createDataSet(PasswordResetToken, 'token');
28
+ usePasswordPolicy(injector);
29
+ };
16
30
  describe('WebSocketApi', () => {
17
31
  it('Should be built', async () => {
18
32
  await usingAsync(new Injector(), async (i) => {
19
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }));
33
+ setupStoresAndDataSets(i);
20
34
  await useWebsockets(i, { port: getPort() });
21
35
  expect(i.getInstance(WebSocketApi)).toBeInstanceOf(WebSocketApi);
22
36
  });
23
37
  });
24
38
  it('Should be built with settings', async () => {
25
39
  await usingAsync(new Injector(), async (i) => {
26
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }));
40
+ setupStoresAndDataSets(i);
27
41
  await useWebsockets(i, { path: '/web-socket', port: getPort() });
28
42
  expect(i.getInstance(WebSocketApi)).toBeInstanceOf(WebSocketApi);
29
43
  });
@@ -31,21 +45,25 @@ describe('WebSocketApi', () => {
31
45
  it('Should broadcast messages', async () => {
32
46
  const port = getPort();
33
47
  await usingAsync(new Injector(), async (i) => {
34
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }));
35
- expect.assertions(5); // All 5 clients should receive the message
48
+ setupStoresAndDataSets(i);
36
49
  await useWebsockets(i, { path: '/web-socket', port });
37
50
  const api = i.getInstance(WebSocketApi);
38
- await Promise.all([1, 2, 3, 4, 5].map(async () => {
51
+ const clients = await Promise.all([1, 2, 3, 4, 5].map(async () => {
39
52
  const client = new WebSocket(`ws://localhost:${port}/web-socket`);
40
- await new Promise((resolve) => client.once('open', () => {
41
- resolve();
42
- }));
43
- client.once('message', (data) => {
44
- expect(data.toString()).toBe('alma');
45
- });
46
- await api.broadcast(({ ws }) => {
47
- ws.send('alma');
48
- });
53
+ await new Promise((resolve) => client.once('open', () => resolve()));
54
+ return client;
55
+ }));
56
+ const messagePromises = clients.map((client) => new Promise((resolve) => {
57
+ client.once('message', (data) => resolve(data.toString()));
58
+ }));
59
+ await api.broadcast(({ ws }) => {
60
+ ws.send('alma');
61
+ });
62
+ const messages = await Promise.all(messagePromises);
63
+ for (const msg of messages) {
64
+ expect(msg).toBe('alma');
65
+ }
66
+ await Promise.all(clients.map(async (client) => {
49
67
  client.close();
50
68
  await new Promise((resolve) => client.once('close', () => resolve()));
51
69
  }));
@@ -54,8 +72,7 @@ describe('WebSocketApi', () => {
54
72
  it('Should receive client messages', async () => {
55
73
  const port = getPort();
56
74
  await usingAsync(new Injector(), async (i) => {
57
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }));
58
- expect.assertions(2); // The action may be invoked twice due to test isolation issues
75
+ setupStoresAndDataSets(i);
59
76
  const data = { value: 'test-message-unique' };
60
77
  let ExampleWsAction = class ExampleWsAction {
61
78
  [Symbol.dispose]() {
@@ -75,7 +92,6 @@ describe('WebSocketApi', () => {
75
92
  }
76
93
  async execute(options) {
77
94
  expect(JSON.parse(options.data.toString())).toEqual(data);
78
- // Send a response back so the client knows the action completed
79
95
  options.socket.send('done');
80
96
  }
81
97
  };
@@ -85,7 +101,6 @@ describe('WebSocketApi', () => {
85
101
  await useWebsockets(i, { path: '/web-socket-test', port, actions: [ExampleWsAction] });
86
102
  const client = new WebSocket(`ws://localhost:${port}/web-socket-test`);
87
103
  await new Promise((resolve) => client.once('open', () => resolve()));
88
- // Wait for the response from the server
89
104
  const responsePromise = new Promise((resolve) => {
90
105
  client.once('message', () => {
91
106
  resolve();
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-api.spec.js","sourceRoot":"","sources":["../src/websocket-api.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"websocket-api.spec.js","sourceRoot":"","sources":["../src/websocket-api.spec.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,9 @@
1
- import { addStore, InMemoryStore, StoreManager, User } from '@furystack/core';
1
+ import { addStore, InMemoryStore, StoreManager, User, useSystemIdentityContext } from '@furystack/core';
2
2
  import { getPort } from '@furystack/core/port-generator';
3
3
  import { Injector } from '@furystack/inject';
4
+ import { getDataSetFor, getRepository } from '@furystack/repository';
4
5
  import { DefaultSession, HttpUserContext, ServerManager, useHttpAuthentication, useRestService, } from '@furystack/rest-service';
6
+ import { PasswordCredential, PasswordResetToken, usePasswordPolicy } from '@furystack/security';
5
7
  import { usingAsync } from '@furystack/utils';
6
8
  import { describe, expect, it, vi } from 'vitest';
7
9
  import { WebSocket } from 'ws';
@@ -21,7 +23,16 @@ describe('WebSocket Integration tests', () => {
21
23
  port,
22
24
  hostName: host,
23
25
  });
24
- addStore(injector, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }));
26
+ addStore(injector, new InMemoryStore({ model: User, primaryKey: 'username' }))
27
+ .addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
28
+ .addStore(new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }))
29
+ .addStore(new InMemoryStore({ model: PasswordResetToken, primaryKey: 'token' }));
30
+ const repo = getRepository(injector);
31
+ repo.createDataSet(User, 'username');
32
+ repo.createDataSet(DefaultSession, 'sessionId');
33
+ repo.createDataSet(PasswordCredential, 'userName');
34
+ repo.createDataSet(PasswordResetToken, 'token');
35
+ usePasswordPolicy(injector);
25
36
  useHttpAuthentication(injector, {});
26
37
  await useWebsockets(injector, { actions: [WhoAmI], path, port, host });
27
38
  const client = await new Promise((resolve, reject) => {
@@ -90,7 +101,9 @@ describe('WebSocket Integration tests', () => {
90
101
  });
91
102
  const whoAmIResult = await getWhoAmIResult(authenticatedClient);
92
103
  expect(whoAmIResult.currentUser).toEqual(testUser);
93
- await userStore.update(testUser.username, { ...testUser, roles: ['newFancyRole'] });
104
+ const systemInjector = useSystemIdentityContext({ injector, username: 'test' });
105
+ const userDataSet = getDataSetFor(systemInjector, User, 'username');
106
+ await userDataSet.update(systemInjector, testUser.username, { ...testUser, roles: ['newFancyRole'] });
94
107
  const updatedWhoAmIResult = await getWhoAmIResult(authenticatedClient);
95
108
  expect(updatedWhoAmIResult.currentUser.roles).toEqual(['newFancyRole']);
96
109
  await userCtx.cookieLogout({
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-integration.spec.js","sourceRoot":"","sources":["../src/websocket-integration.spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"websocket-integration.spec.js","sourceRoot":"","sources":["../src/websocket-integration.spec.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@furystack/websocket-api",
3
- "version": "13.1.11",
3
+ "version": "13.1.12",
4
4
  "description": "WebSocket API implementation for FuryStack",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -37,13 +37,15 @@
37
37
  },
38
38
  "homepage": "https://github.com/furystack/furystack",
39
39
  "dependencies": {
40
- "@furystack/core": "^15.2.0",
40
+ "@furystack/core": "^15.2.1",
41
41
  "@furystack/inject": "^12.0.30",
42
- "@furystack/rest-service": "^11.0.7",
42
+ "@furystack/rest-service": "^12.0.0",
43
43
  "@furystack/utils": "^8.1.10",
44
44
  "ws": "^8.19.0"
45
45
  },
46
46
  "devDependencies": {
47
+ "@furystack/repository": "^10.1.2",
48
+ "@furystack/security": "^7.0.0",
47
49
  "@types/ws": "^8.18.1",
48
50
  "typescript": "^5.9.3",
49
51
  "vitest": "^4.0.18"
@@ -1,7 +1,9 @@
1
1
  import { InMemoryStore, User, addStore } from '@furystack/core'
2
2
  import { getPort } from '@furystack/core/port-generator'
3
3
  import { Injectable, Injector } from '@furystack/inject'
4
+ import { getRepository } from '@furystack/repository'
4
5
  import { DefaultSession } from '@furystack/rest-service'
6
+ import { PasswordCredential, PasswordResetToken, usePasswordPolicy } from '@furystack/security'
5
7
  import { usingAsync } from '@furystack/utils'
6
8
  import { describe, expect, it } from 'vitest'
7
9
  import { WebSocket, type Data } from 'ws'
@@ -9,22 +11,32 @@ import { useWebsockets } from './helpers.js'
9
11
  import type { WebSocketAction } from './models/websocket-action.js'
10
12
  import { WebSocketApi } from './websocket-api.js'
11
13
 
14
+ const setupStoresAndDataSets = (injector: Injector) => {
15
+ addStore(injector, new InMemoryStore({ model: User, primaryKey: 'username' }))
16
+ .addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
17
+ .addStore(new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }))
18
+ .addStore(new InMemoryStore({ model: PasswordResetToken, primaryKey: 'token' }))
19
+
20
+ const repo = getRepository(injector)
21
+ repo.createDataSet(User, 'username')
22
+ repo.createDataSet(DefaultSession, 'sessionId')
23
+ repo.createDataSet(PasswordCredential, 'userName')
24
+ repo.createDataSet(PasswordResetToken, 'token')
25
+
26
+ usePasswordPolicy(injector)
27
+ }
28
+
12
29
  describe('WebSocketApi', () => {
13
30
  it('Should be built', async () => {
14
31
  await usingAsync(new Injector(), async (i) => {
15
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(
16
- new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }),
17
- )
32
+ setupStoresAndDataSets(i)
18
33
  await useWebsockets(i, { port: getPort() })
19
34
  expect(i.getInstance(WebSocketApi)).toBeInstanceOf(WebSocketApi)
20
35
  })
21
36
  })
22
37
  it('Should be built with settings', async () => {
23
38
  await usingAsync(new Injector(), async (i) => {
24
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(
25
- new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }),
26
- )
27
-
39
+ setupStoresAndDataSets(i)
28
40
  await useWebsockets(i, { path: '/web-socket', port: getPort() })
29
41
  expect(i.getInstance(WebSocketApi)).toBeInstanceOf(WebSocketApi)
30
42
  })
@@ -33,27 +45,37 @@ describe('WebSocketApi', () => {
33
45
  it('Should broadcast messages', async () => {
34
46
  const port = getPort()
35
47
  await usingAsync(new Injector(), async (i) => {
36
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(
37
- new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }),
38
- )
48
+ setupStoresAndDataSets(i)
39
49
 
40
- expect.assertions(5) // All 5 clients should receive the message
41
50
  await useWebsockets(i, { path: '/web-socket', port })
42
51
  const api = i.getInstance(WebSocketApi)
43
- await Promise.all(
52
+
53
+ const clients = await Promise.all(
44
54
  [1, 2, 3, 4, 5].map(async () => {
45
55
  const client = new WebSocket(`ws://localhost:${port}/web-socket`)
46
- await new Promise<void>((resolve) =>
47
- client.once('open', () => {
48
- resolve()
49
- }),
50
- )
51
- client.once('message', (data) => {
52
- expect((data as Buffer).toString()).toBe('alma')
53
- })
54
- await api.broadcast(({ ws }) => {
55
- ws.send('alma')
56
- })
56
+ await new Promise<void>((resolve) => client.once('open', () => resolve()))
57
+ return client
58
+ }),
59
+ )
60
+
61
+ const messagePromises = clients.map(
62
+ (client) =>
63
+ new Promise<string>((resolve) => {
64
+ client.once('message', (data) => resolve((data as Buffer).toString()))
65
+ }),
66
+ )
67
+
68
+ await api.broadcast(({ ws }) => {
69
+ ws.send('alma')
70
+ })
71
+
72
+ const messages = await Promise.all(messagePromises)
73
+ for (const msg of messages) {
74
+ expect(msg).toBe('alma')
75
+ }
76
+
77
+ await Promise.all(
78
+ clients.map(async (client) => {
57
79
  client.close()
58
80
  await new Promise<void>((resolve) => client.once('close', () => resolve()))
59
81
  }),
@@ -64,11 +86,8 @@ describe('WebSocketApi', () => {
64
86
  it('Should receive client messages', async () => {
65
87
  const port = getPort()
66
88
  await usingAsync(new Injector(), async (i) => {
67
- addStore(i, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(
68
- new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }),
69
- )
89
+ setupStoresAndDataSets(i)
70
90
 
71
- expect.assertions(2) // The action may be invoked twice due to test isolation issues
72
91
  const data = { value: 'test-message-unique' }
73
92
  @Injectable()
74
93
  class ExampleWsAction implements WebSocketAction {
@@ -91,7 +110,6 @@ describe('WebSocketApi', () => {
91
110
 
92
111
  public async execute(options: { data: Data; socket: WebSocket }) {
93
112
  expect(JSON.parse((options.data as Buffer).toString())).toEqual(data)
94
- // Send a response back so the client knows the action completed
95
113
  options.socket.send('done')
96
114
  }
97
115
  }
@@ -100,7 +118,6 @@ describe('WebSocketApi', () => {
100
118
  const client = new WebSocket(`ws://localhost:${port}/web-socket-test`)
101
119
  await new Promise<void>((resolve) => client.once('open', () => resolve()))
102
120
 
103
- // Wait for the response from the server
104
121
  const responsePromise = new Promise<void>((resolve) => {
105
122
  client.once('message', () => {
106
123
  resolve()
@@ -1,6 +1,7 @@
1
- import { addStore, InMemoryStore, StoreManager, User } from '@furystack/core'
1
+ import { addStore, InMemoryStore, StoreManager, User, useSystemIdentityContext } from '@furystack/core'
2
2
  import { getPort } from '@furystack/core/port-generator'
3
3
  import { Injector } from '@furystack/inject'
4
+ import { getDataSetFor, getRepository } from '@furystack/repository'
4
5
  import {
5
6
  DefaultSession,
6
7
  HttpUserContext,
@@ -8,6 +9,7 @@ import {
8
9
  useHttpAuthentication,
9
10
  useRestService,
10
11
  } from '@furystack/rest-service'
12
+ import { PasswordCredential, PasswordResetToken, usePasswordPolicy } from '@furystack/security'
11
13
  import { usingAsync } from '@furystack/utils'
12
14
  import { describe, expect, it, vi } from 'vitest'
13
15
  import { WebSocket } from 'ws'
@@ -30,9 +32,18 @@ describe('WebSocket Integration tests', () => {
30
32
  port,
31
33
  hostName: host,
32
34
  })
33
- addStore(injector, new InMemoryStore({ model: User, primaryKey: 'username' })).addStore(
34
- new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }),
35
- )
35
+ addStore(injector, new InMemoryStore({ model: User, primaryKey: 'username' }))
36
+ .addStore(new InMemoryStore({ model: DefaultSession, primaryKey: 'sessionId' }))
37
+ .addStore(new InMemoryStore({ model: PasswordCredential, primaryKey: 'userName' }))
38
+ .addStore(new InMemoryStore({ model: PasswordResetToken, primaryKey: 'token' }))
39
+
40
+ const repo = getRepository(injector)
41
+ repo.createDataSet(User, 'username')
42
+ repo.createDataSet(DefaultSession, 'sessionId')
43
+ repo.createDataSet(PasswordCredential, 'userName')
44
+ repo.createDataSet(PasswordResetToken, 'token')
45
+
46
+ usePasswordPolicy(injector)
36
47
  useHttpAuthentication(injector, {})
37
48
  await useWebsockets(injector, { actions: [WhoAmI], path, port, host })
38
49
 
@@ -111,7 +122,9 @@ describe('WebSocket Integration tests', () => {
111
122
  const whoAmIResult = await getWhoAmIResult(authenticatedClient)
112
123
  expect(whoAmIResult.currentUser).toEqual(testUser)
113
124
 
114
- await userStore.update(testUser.username, { ...testUser, roles: ['newFancyRole'] })
125
+ const systemInjector = useSystemIdentityContext({ injector, username: 'test' })
126
+ const userDataSet = getDataSetFor(systemInjector, User, 'username')
127
+ await userDataSet.update(systemInjector, testUser.username, { ...testUser, roles: ['newFancyRole'] })
115
128
 
116
129
  const updatedWhoAmIResult = await getWhoAmIResult(authenticatedClient)
117
130
  expect(updatedWhoAmIResult.currentUser.roles).toEqual(['newFancyRole'])