redis-smq-web-server 9.0.0-next.1 → 9.0.0-next.11

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 (107) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +99 -69
  3. package/dist/cjs/bin/cli.d.ts +1 -0
  4. package/dist/cjs/bin/cli.js +42 -7
  5. package/dist/cjs/bin/cli.js.map +1 -1
  6. package/dist/cjs/src/config/parse-config.d.ts.map +1 -1
  7. package/dist/cjs/src/config/parse-config.js +16 -29
  8. package/dist/cjs/src/config/parse-config.js.map +1 -1
  9. package/dist/cjs/src/config/types/index.d.ts +16 -5
  10. package/dist/cjs/src/config/types/index.d.ts.map +1 -1
  11. package/dist/cjs/src/index.d.ts +4 -1
  12. package/dist/cjs/src/index.d.ts.map +1 -1
  13. package/dist/cjs/src/index.js +54 -25
  14. package/dist/cjs/src/index.js.map +1 -1
  15. package/dist/cjs/tests/common/config.d.ts +3 -0
  16. package/dist/cjs/tests/common/config.d.ts.map +1 -0
  17. package/dist/cjs/tests/common/config.js +24 -0
  18. package/dist/cjs/tests/common/config.js.map +1 -0
  19. package/dist/cjs/tests/common/redis-client.d.ts +94 -0
  20. package/dist/cjs/tests/common/redis-client.d.ts.map +1 -0
  21. package/dist/cjs/tests/common/redis-client.js +40 -0
  22. package/dist/cjs/tests/common/redis-client.js.map +1 -0
  23. package/dist/cjs/tests/common/start-api-server.d.ts +3 -0
  24. package/dist/cjs/tests/common/start-api-server.d.ts.map +1 -0
  25. package/dist/cjs/tests/common/start-api-server.js +38 -0
  26. package/dist/cjs/tests/common/start-api-server.js.map +1 -0
  27. package/dist/cjs/tests/common/start-cli.d.ts +10 -0
  28. package/dist/cjs/tests/common/start-cli.d.ts.map +1 -0
  29. package/dist/cjs/tests/common/start-cli.js +70 -0
  30. package/dist/cjs/tests/common/start-cli.js.map +1 -0
  31. package/dist/cjs/tests/common/start-redis-server.d.ts +3 -0
  32. package/dist/cjs/tests/common/start-redis-server.d.ts.map +1 -0
  33. package/dist/cjs/tests/common/start-redis-server.js +37 -0
  34. package/dist/cjs/tests/common/start-redis-server.js.map +1 -0
  35. package/dist/cjs/tests/common/start-web-server.d.ts +3 -0
  36. package/dist/cjs/tests/common/start-web-server.d.ts.map +1 -0
  37. package/dist/cjs/tests/common/start-web-server.js +33 -0
  38. package/dist/cjs/tests/common/start-web-server.js.map +1 -0
  39. package/dist/cjs/tests/setup.d.ts +2 -0
  40. package/dist/cjs/tests/setup.d.ts.map +1 -0
  41. package/dist/cjs/tests/setup.js +27 -0
  42. package/dist/cjs/tests/setup.js.map +1 -0
  43. package/dist/cjs/tests/tests/test00001.test.d.ts +2 -0
  44. package/dist/cjs/tests/tests/test00001.test.d.ts.map +1 -0
  45. package/dist/cjs/tests/tests/test00001.test.js +118 -0
  46. package/dist/cjs/tests/tests/test00001.test.js.map +1 -0
  47. package/dist/cjs/tests/tests/test00002.test.d.ts +2 -0
  48. package/dist/cjs/tests/tests/test00002.test.d.ts.map +1 -0
  49. package/dist/cjs/tests/tests/test00002.test.js +68 -0
  50. package/dist/cjs/tests/tests/test00002.test.js.map +1 -0
  51. package/dist/cjs/tests/tests/test00003.test.d.ts +2 -0
  52. package/dist/cjs/tests/tests/test00003.test.d.ts.map +1 -0
  53. package/dist/cjs/tests/tests/test00003.test.js +117 -0
  54. package/dist/cjs/tests/tests/test00003.test.js.map +1 -0
  55. package/dist/esm/bin/cli.d.ts +1 -0
  56. package/dist/esm/bin/cli.js +41 -7
  57. package/dist/esm/bin/cli.js.map +1 -1
  58. package/dist/esm/src/config/parse-config.d.ts.map +1 -1
  59. package/dist/esm/src/config/parse-config.js +18 -28
  60. package/dist/esm/src/config/parse-config.js.map +1 -1
  61. package/dist/esm/src/config/types/index.d.ts +16 -5
  62. package/dist/esm/src/config/types/index.d.ts.map +1 -1
  63. package/dist/esm/src/index.d.ts +4 -1
  64. package/dist/esm/src/index.d.ts.map +1 -1
  65. package/dist/esm/src/index.js +55 -25
  66. package/dist/esm/src/index.js.map +1 -1
  67. package/dist/esm/tests/common/config.d.ts +3 -0
  68. package/dist/esm/tests/common/config.d.ts.map +1 -0
  69. package/dist/esm/tests/common/config.js +21 -0
  70. package/dist/esm/tests/common/config.js.map +1 -0
  71. package/dist/esm/tests/common/redis-client.d.ts +94 -0
  72. package/dist/esm/tests/common/redis-client.d.ts.map +1 -0
  73. package/dist/esm/tests/common/redis-client.js +20 -0
  74. package/dist/esm/tests/common/redis-client.js.map +1 -0
  75. package/dist/esm/tests/common/start-api-server.d.ts +3 -0
  76. package/dist/esm/tests/common/start-api-server.d.ts.map +1 -0
  77. package/dist/esm/tests/common/start-api-server.js +21 -0
  78. package/dist/esm/tests/common/start-api-server.js.map +1 -0
  79. package/dist/esm/tests/common/start-cli.d.ts +10 -0
  80. package/dist/esm/tests/common/start-cli.d.ts.map +1 -0
  81. package/dist/esm/tests/common/start-cli.js +54 -0
  82. package/dist/esm/tests/common/start-cli.js.map +1 -0
  83. package/dist/esm/tests/common/start-redis-server.d.ts +3 -0
  84. package/dist/esm/tests/common/start-redis-server.d.ts.map +1 -0
  85. package/dist/esm/tests/common/start-redis-server.js +22 -0
  86. package/dist/esm/tests/common/start-redis-server.js.map +1 -0
  87. package/dist/esm/tests/common/start-web-server.d.ts +3 -0
  88. package/dist/esm/tests/common/start-web-server.d.ts.map +1 -0
  89. package/dist/esm/tests/common/start-web-server.js +16 -0
  90. package/dist/esm/tests/common/start-web-server.js.map +1 -0
  91. package/dist/esm/tests/setup.d.ts +2 -0
  92. package/dist/esm/tests/setup.d.ts.map +1 -0
  93. package/dist/esm/tests/setup.js +16 -0
  94. package/dist/esm/tests/setup.js.map +1 -0
  95. package/dist/esm/tests/tests/test00001.test.d.ts +2 -0
  96. package/dist/esm/tests/tests/test00001.test.d.ts.map +1 -0
  97. package/dist/esm/tests/tests/test00001.test.js +103 -0
  98. package/dist/esm/tests/tests/test00001.test.js.map +1 -0
  99. package/dist/esm/tests/tests/test00002.test.d.ts +2 -0
  100. package/dist/esm/tests/tests/test00002.test.d.ts.map +1 -0
  101. package/dist/esm/tests/tests/test00002.test.js +57 -0
  102. package/dist/esm/tests/tests/test00002.test.js.map +1 -0
  103. package/dist/esm/tests/tests/test00003.test.d.ts +2 -0
  104. package/dist/esm/tests/tests/test00003.test.d.ts.map +1 -0
  105. package/dist/esm/tests/tests/test00003.test.js +102 -0
  106. package/dist/esm/tests/tests/test00003.test.js.map +1 -0
  107. package/package.json +19 -8
@@ -0,0 +1,103 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import request from 'supertest';
3
+ import { config } from '../common/config.js';
4
+ import { shutdownWebServer, startWebServer, } from '../common/start-web-server.js';
5
+ describe('RedisSMQWebServer E2E Tests', () => {
6
+ const serverUrl = `http://localhost:${config.webServer?.port}`;
7
+ it('should serve index.html for root path', async () => {
8
+ await startWebServer();
9
+ const response = await request(serverUrl)
10
+ .get('/')
11
+ .expect(200)
12
+ .expect('Content-Type', /text\/html/);
13
+ expect(response.text).toContain('<!doctype html>');
14
+ });
15
+ it('should inject web UI config into index.html', async () => {
16
+ await startWebServer();
17
+ const response = await request(serverUrl).get('/').expect(200);
18
+ expect(response.text).toContain('window.configs');
19
+ expect(response.text).toContain('"BASE_PATH":"/"');
20
+ expect(response.text).toContain('"API_URL":"/"');
21
+ });
22
+ it('should set cache headers for asset files', async () => {
23
+ await startWebServer();
24
+ const response = await request(serverUrl).get('/index.html').expect(200);
25
+ expect(response.headers['cache-control']).toContain('no-cache');
26
+ const match = response.text.match(/<script[^>]+src=["']([^"']+)["']/i);
27
+ expect(match, 'index.html should include at least one script tag with src').toBeTruthy();
28
+ const scriptSrc = match?.[1] || '';
29
+ expect(scriptSrc.length).toBeGreaterThan(0);
30
+ const assetPath = scriptSrc.startsWith('http')
31
+ ? scriptSrc.replace(serverUrl, '')
32
+ : scriptSrc;
33
+ const assetRes = await request(serverUrl).get(assetPath).expect(200);
34
+ expect(assetRes.headers['cache-control']).toBeDefined();
35
+ });
36
+ it('should return 404 for non-existent static files', async () => {
37
+ await startWebServer();
38
+ await request(serverUrl)
39
+ .get('/assets/non-existent-file-12345.js')
40
+ .expect(404);
41
+ });
42
+ it('should set ETag header for static files', async () => {
43
+ await startWebServer();
44
+ const response = await request(serverUrl).get('/').expect(200);
45
+ expect(response.headers['etag']).toBeDefined();
46
+ });
47
+ it('should route /api requests to embedded REST API', async () => {
48
+ await startWebServer();
49
+ await request(serverUrl)
50
+ .get('/api/v1/queues')
51
+ .expect(200)
52
+ .expect('Content-Type', /application\/json/);
53
+ });
54
+ it('should serve index.html for non-API routes', async () => {
55
+ await startWebServer();
56
+ const response = await request(serverUrl)
57
+ .get('/queues/my-queue/messages/123/details')
58
+ .expect(200)
59
+ .expect('Content-Type', /text\/html/);
60
+ expect(response.text).toContain('<!doctype html>');
61
+ });
62
+ it('should not serve index.html for /api routes', async () => {
63
+ await startWebServer();
64
+ const response = await request(serverUrl).get('/api/v1/queues');
65
+ expect(response.headers['content-type']).not.toContain('text/html');
66
+ });
67
+ it('should not serve index.html for /docs routes', async () => {
68
+ await startWebServer();
69
+ const response = await request(serverUrl).get('/docs');
70
+ expect(response.text).toContain('Swagger UI');
71
+ });
72
+ it('should include rate limit headers', async () => {
73
+ await startWebServer();
74
+ const response = await request(serverUrl).get('/');
75
+ expect(response.headers['x-ratelimit-limit']).toBeDefined();
76
+ expect(response.headers['x-ratelimit-remaining']).toBeDefined();
77
+ });
78
+ it('should handle concurrent requests', async () => {
79
+ await startWebServer();
80
+ const requests = Array(50)
81
+ .fill(null)
82
+ .map(() => request(serverUrl).get('/'));
83
+ const responses = await Promise.all(requests);
84
+ const successfulResponses = responses.filter((r) => r.status === 200);
85
+ expect(successfulResponses.length).toBe(50);
86
+ });
87
+ it('should shutdown gracefully', async () => {
88
+ await startWebServer();
89
+ await new Promise((resolve) => setTimeout(resolve, 500));
90
+ let response = await request(serverUrl).get('/');
91
+ expect(response.status).toBe(200);
92
+ await shutdownWebServer();
93
+ await new Promise((resolve) => setTimeout(resolve, 500));
94
+ try {
95
+ response = await request(serverUrl).get('/');
96
+ expect(response.status).not.toBe(200);
97
+ }
98
+ catch (err) {
99
+ expect(err).toBeDefined();
100
+ }
101
+ });
102
+ });
103
+ //# sourceMappingURL=test00001.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test00001.test.js","sourceRoot":"","sources":["../../../../tests/tests/test00001.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test00002.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test00002.test.d.ts","sourceRoot":"","sources":["../../../../tests/tests/test00002.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import request from 'supertest';
3
+ import { startApiServer, stopApiServer } from '../common/start-api-server.js';
4
+ import { RedisSMQWebServer } from '../../index.js';
5
+ import { config } from '../common/config.js';
6
+ import { net } from 'redis-smq-common';
7
+ describe('RedisSMQWebServer with apiProxyTarget', () => {
8
+ let webServerUrl;
9
+ let webServer;
10
+ beforeEach(async () => {
11
+ const apiPort = await startApiServer();
12
+ const apiProxyTarget = `http://127.0.0.1:${apiPort}`;
13
+ const webServerPort = await net.getRandomPort();
14
+ webServer = new RedisSMQWebServer({
15
+ ...config,
16
+ webServer: {
17
+ port: webServerPort,
18
+ apiProxyTarget,
19
+ },
20
+ });
21
+ await webServer.run();
22
+ webServerUrl = `http://127.0.0.1:${webServerPort}`;
23
+ });
24
+ afterEach(async () => {
25
+ await webServer.shutdown();
26
+ await stopApiServer();
27
+ });
28
+ it('proxies /api/v1 endpoints', async () => {
29
+ await request(webServerUrl)
30
+ .get('/api/v1/queues')
31
+ .expect(200)
32
+ .expect('Content-Type', /application\/json/);
33
+ });
34
+ it('proxies /docs', async () => {
35
+ const res = await request(webServerUrl).get('/docs').expect(200);
36
+ expect(res.text).toContain('Swagger UI');
37
+ });
38
+ it('serves SPA index.html for non-API routes', async () => {
39
+ const res = await request(webServerUrl)
40
+ .get('/queues/my-queue')
41
+ .expect(200)
42
+ .expect('Content-Type', /text\/html/);
43
+ expect(res.text).toContain('<!doctype html>');
44
+ });
45
+ it('serves assets as static files', async () => {
46
+ const res = await request(webServerUrl).get('/').expect(200);
47
+ const match = res.text.match(/<script[^>]+src=["']([^"']+)["']/i);
48
+ expect(match).toBeTruthy();
49
+ const scriptSrc = match?.[1] || '';
50
+ const assetPath = scriptSrc.startsWith('http')
51
+ ? scriptSrc.replace(webServerUrl, '')
52
+ : scriptSrc;
53
+ const assetRes = await request(webServerUrl).get(assetPath).expect(200);
54
+ expect(assetRes.headers['cache-control']).toBeDefined();
55
+ });
56
+ });
57
+ //# sourceMappingURL=test00002.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test00002.test.js","sourceRoot":"","sources":["../../../../tests/tests/test00002.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=test00003.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test00003.test.d.ts","sourceRoot":"","sources":["../../../../tests/tests/test00003.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,102 @@
1
+ import { afterAll, beforeAll, describe, expect, it } from 'vitest';
2
+ import request from 'supertest';
3
+ import { startApiServer, stopApiServer } from '../common/start-api-server.js';
4
+ import { startCliWithArgs } from '../common/start-cli.js';
5
+ describe('RedisSMQ Web Server CLI e2e tests', () => {
6
+ describe('serves SPA with default basePath "/"', () => {
7
+ let started;
8
+ beforeAll(async () => {
9
+ started = await startCliWithArgs([
10
+ '--base-path',
11
+ '/',
12
+ '--enable-log',
13
+ '0',
14
+ ]);
15
+ });
16
+ afterAll(async () => {
17
+ await started.stop();
18
+ });
19
+ it('returns index.html for / and caches assets', async () => {
20
+ const res = await request(started.url).get('/index.html').expect(200);
21
+ expect(res.headers['content-type']).toMatch(/text\/html/);
22
+ expect(res.headers['cache-control']).toMatch(/no-cache/);
23
+ const match = res.text.match(/<script[^>]+src=["']([^"']+)["']/i);
24
+ expect(match).toBeTruthy();
25
+ const scriptSrc = match?.[1] ?? '';
26
+ const assetPath = scriptSrc.startsWith('http')
27
+ ? scriptSrc.replace(started.url, '')
28
+ : scriptSrc;
29
+ const assetRes = await request(started.url).get(assetPath).expect(200);
30
+ expect(assetRes.headers['cache-control']).toBeDefined();
31
+ expect(assetRes.headers['cache-control']).toMatch(/max-age=\d+/);
32
+ });
33
+ it('SPA fallback works on non-API route', async () => {
34
+ const res = await request(started.url).get('/queues/demo').expect(200);
35
+ expect(res.headers['content-type']).toMatch(/text\/html/);
36
+ });
37
+ });
38
+ describe('respects custom basePath "/ui"', () => {
39
+ let started;
40
+ beforeAll(async () => {
41
+ started = await startCliWithArgs([
42
+ '--base-path',
43
+ '/ui',
44
+ '--enable-log',
45
+ '0',
46
+ ]);
47
+ });
48
+ afterAll(async () => {
49
+ await started.stop();
50
+ });
51
+ it('redirects "/" to "/ui"', async () => {
52
+ const res = await request(started.url).get('/').expect(302);
53
+ expect(res.headers.location).toBe('/ui');
54
+ });
55
+ it('serves index.html at "/ui" and SPA fallback under it', async () => {
56
+ const res = await request(started.url).get('/ui').expect(200);
57
+ expect(res.headers['content-type']).toMatch(/text\/html/);
58
+ const sub = await request(started.url).get('/ui/queues').expect(200);
59
+ expect(sub.headers['content-type']).toMatch(/text\/html/);
60
+ });
61
+ it('serves api requests under custom basePath', async () => {
62
+ await request(started.url)
63
+ .get('/ui/api/v1/queues')
64
+ .expect((r) => {
65
+ expect(r.headers['content-type']).not.toMatch(/text\/html/);
66
+ });
67
+ });
68
+ });
69
+ describe('proxies API when apiProxyTarget is set', () => {
70
+ let started;
71
+ beforeAll(async () => {
72
+ const port = await startApiServer();
73
+ started = await startCliWithArgs([
74
+ '--base-path',
75
+ '/',
76
+ '--api-proxy-target',
77
+ `http://127.0.0.1:${port}`,
78
+ '--enable-log',
79
+ '0',
80
+ ]);
81
+ });
82
+ afterAll(async () => {
83
+ await started.stop();
84
+ await stopApiServer();
85
+ });
86
+ it('proxies /api/v1 endpoints', async () => {
87
+ await request(started.url)
88
+ .get('/api/v1/queues')
89
+ .expect(200)
90
+ .expect('Content-Type', /application\/json/);
91
+ });
92
+ it('proxies /docs', async () => {
93
+ const res = await request(started.url).get('/docs').expect(200);
94
+ expect(res.text).toMatch(/<html|<!doctype/i);
95
+ });
96
+ it('keeps SPA behavior for non-API routes', async () => {
97
+ const res = await request(started.url).get('/about').expect(200);
98
+ expect(res.headers['content-type']).toMatch(/text\/html/);
99
+ });
100
+ });
101
+ });
102
+ //# sourceMappingURL=test00003.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test00003.test.js","sourceRoot":"","sources":["../../../../tests/tests/test00003.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "redis-smq-web-server",
3
- "version": "9.0.0-next.1",
3
+ "version": "9.0.0-next.11",
4
4
  "description": "Web server for RedisSMQ Web UI: serves the SPA and hosts or proxies the RedisSMQ REST API.",
5
5
  "author": "Weyoss <weyoss@protonmail.com>",
6
6
  "license": "MIT",
@@ -35,18 +35,29 @@
35
35
  "redis-smq-web-server": "./dist/esm/bin/cli.js"
36
36
  },
37
37
  "dependencies": {
38
- "commander": "13.1.0",
38
+ "commander": "14.0.1",
39
39
  "express": "4.21.2",
40
- "http-proxy-middleware": "3.0.5",
41
- "ioredis": "5.5.0"
40
+ "express-rate-limit": "8.1.0",
41
+ "http-proxy-middleware": "3.0.5"
42
42
  },
43
43
  "devDependencies": {
44
44
  "@types/express": "4.17.23"
45
45
  },
46
46
  "peerDependencies": {
47
- "redis-smq-common": "^9.0.0-next.1",
48
- "redis-smq-rest-api": "^9.0.0-next.1",
49
- "redis-smq-web-ui": "^9.0.0-next.1"
47
+ "@redis/client": "^5",
48
+ "ioredis": "^5",
49
+ "redis-smq-rest-api": "^9.0.0-next.11",
50
+ "redis-smq-web-ui": "^9.0.0-next.11",
51
+ "redis-smq-common": "^9.0.0-next.11",
52
+ "redis-smq": "^9.0.0-next.11"
53
+ },
54
+ "peerDependenciesMeta": {
55
+ "@redis/client": {
56
+ "optional": true
57
+ },
58
+ "ioredis": {
59
+ "optional": true
60
+ }
50
61
  },
51
62
  "engineStrict": true,
52
63
  "engines": {
@@ -55,6 +66,6 @@
55
66
  "scripts": {
56
67
  "build": "scripts/build.sh",
57
68
  "dev": "tsc -w & node --watch dist/index.js",
58
- "test": "vitest run --passWithNoTests"
69
+ "test": "../../scripts/test_workspace_esm.sh"
59
70
  }
60
71
  }