redis-smq-web-server 9.0.0-next.10 → 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.
- package/CHANGELOG.md +10 -0
- package/README.md +1 -1
- package/dist/cjs/tests/common/start-api-server.d.ts +3 -0
- package/dist/cjs/tests/common/start-api-server.d.ts.map +1 -0
- package/dist/cjs/tests/common/start-api-server.js +38 -0
- package/dist/cjs/tests/common/start-api-server.js.map +1 -0
- package/dist/cjs/tests/common/start-cli.d.ts +10 -0
- package/dist/cjs/tests/common/start-cli.d.ts.map +1 -0
- package/dist/cjs/tests/common/start-cli.js +70 -0
- package/dist/cjs/tests/common/start-cli.js.map +1 -0
- package/dist/cjs/tests/tests/test00002.test.d.ts +2 -0
- package/dist/cjs/tests/tests/test00002.test.d.ts.map +1 -0
- package/dist/cjs/tests/tests/test00002.test.js +68 -0
- package/dist/cjs/tests/tests/test00002.test.js.map +1 -0
- package/dist/cjs/tests/tests/test00003.test.d.ts +2 -0
- package/dist/cjs/tests/tests/test00003.test.d.ts.map +1 -0
- package/dist/cjs/tests/tests/test00003.test.js +117 -0
- package/dist/cjs/tests/tests/test00003.test.js.map +1 -0
- package/dist/esm/tests/common/start-api-server.d.ts +3 -0
- package/dist/esm/tests/common/start-api-server.d.ts.map +1 -0
- package/dist/esm/tests/common/start-api-server.js +21 -0
- package/dist/esm/tests/common/start-api-server.js.map +1 -0
- package/dist/esm/tests/common/start-cli.d.ts +10 -0
- package/dist/esm/tests/common/start-cli.d.ts.map +1 -0
- package/dist/esm/tests/common/start-cli.js +54 -0
- package/dist/esm/tests/common/start-cli.js.map +1 -0
- package/dist/esm/tests/tests/test00002.test.d.ts +2 -0
- package/dist/esm/tests/tests/test00002.test.d.ts.map +1 -0
- package/dist/esm/tests/tests/test00002.test.js +57 -0
- package/dist/esm/tests/tests/test00002.test.js.map +1 -0
- package/dist/esm/tests/tests/test00003.test.d.ts +2 -0
- package/dist/esm/tests/tests/test00003.test.d.ts.map +1 -0
- package/dist/esm/tests/tests/test00003.test.js +102 -0
- package/dist/esm/tests/tests/test00003.test.js.map +1 -0
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,16 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## [9.0.0-next.11](https://github.com/weyoss/redis-smq/compare/v9.0.0-next.10...v9.0.0-next.11) (2025-10-27)
|
|
7
|
+
|
|
8
|
+
### 🐛 Bug Fixes
|
|
9
|
+
|
|
10
|
+
- correct codecov badge URL format ([3ebb5c8](https://github.com/weyoss/redis-smq/commit/3ebb5c8ba8a7f9902de054d7aaf0c1fc572fb9a6))
|
|
11
|
+
|
|
12
|
+
### ✅ Tests
|
|
13
|
+
|
|
14
|
+
- **redis-smq-web-server:** add CLI and API proxy e2e tests ([a96ee8e](https://github.com/weyoss/redis-smq/commit/a96ee8e5a91f7a36dcd0a66082fc0b25be62350f))
|
|
15
|
+
|
|
6
16
|
## [9.0.0-next.10](https://github.com/weyoss/redis-smq/compare/v9.0.0-next.9...v9.0.0-next.10) (2025-10-26)
|
|
7
17
|
|
|
8
18
|
### 🐛 Bug Fixes
|
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
> - Install stable packages with @latest; pre-release with @next.
|
|
10
10
|
|
|
11
11
|
[](https://www.npmjs.com/package/redis-smq-web-server?activeTab=versions)
|
|
12
|
-
[](https://img.shields.io/codecov/c/github/weyoss/redis-smq/next?flag=redis-smq-web-server&style=flat-square)](https://app.codecov.io/github/weyoss/redis-smq/tree/next/packages/redis-smq-web-server)
|
|
13
13
|
|
|
14
14
|
A lightweight, configurable HTTP server that hosts the RedisSMQ Web UI and exposes the RedisSMQ HTTP API in the same process — or proxies it to an external API service.
|
|
15
15
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-api-server.d.ts","sourceRoot":"","sources":["../../../../tests/common/start-api-server.ts"],"names":[],"mappings":"AAeA,wBAAsB,cAAc,gCASnC;AAED,wBAAsB,aAAa,kBAKlC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.startApiServer = startApiServer;
|
|
13
|
+
exports.stopApiServer = stopApiServer;
|
|
14
|
+
const redis_smq_common_1 = require("redis-smq-common");
|
|
15
|
+
const config_js_1 = require("./config.js");
|
|
16
|
+
const redis_smq_rest_api_1 = require("redis-smq-rest-api");
|
|
17
|
+
let server = null;
|
|
18
|
+
function startApiServer() {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
if (!server) {
|
|
21
|
+
const port = yield redis_smq_common_1.net.getRandomPort();
|
|
22
|
+
config_js_1.config.apiServer = config_js_1.config.apiServer || {};
|
|
23
|
+
config_js_1.config.apiServer.port = port;
|
|
24
|
+
server = new redis_smq_rest_api_1.RedisSMQRestApi(config_js_1.config);
|
|
25
|
+
yield server.run();
|
|
26
|
+
return port;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
function stopApiServer() {
|
|
31
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
32
|
+
if (server) {
|
|
33
|
+
yield server.shutdown();
|
|
34
|
+
server = null;
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=start-api-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-api-server.js","sourceRoot":"","sources":["../../../../tests/common/start-api-server.ts"],"names":[],"mappings":";;;;;;;;;;;AAeA,wCASC;AAED,sCAKC;AAtBD,uDAAuC;AACvC,2CAAqC;AACrC,2DAAqD;AAErD,IAAI,MAAM,GAA2B,IAAI,CAAC;AAE1C,SAAsB,cAAc;;QAClC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,sBAAG,CAAC,aAAa,EAAE,CAAC;YACvC,kBAAM,CAAC,SAAS,GAAG,kBAAM,CAAC,SAAS,IAAI,EAAE,CAAC;YAC1C,kBAAM,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC;YAC7B,MAAM,GAAG,IAAI,oCAAe,CAAC,kBAAM,CAAC,CAAC;YACrC,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;YACnB,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CAAA;AAED,SAAsB,aAAa;;QACjC,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;YACxB,MAAM,GAAG,IAAI,CAAC;QAChB,CAAC;IACH,CAAC;CAAA"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
export type StartedProcess = {
|
|
3
|
+
proc: ReturnType<typeof spawn>;
|
|
4
|
+
url: string;
|
|
5
|
+
stop: () => Promise<void>;
|
|
6
|
+
stdout: string[];
|
|
7
|
+
stderr: string[];
|
|
8
|
+
};
|
|
9
|
+
export declare function startCliWithArgs(args: string[]): Promise<StartedProcess>;
|
|
10
|
+
//# sourceMappingURL=start-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-cli.d.ts","sourceRoot":"","sources":["../../../../tests/common/start-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAMtC,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,cAAc,CAAC,CAyDzB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.startCliWithArgs = startCliWithArgs;
|
|
16
|
+
const child_process_1 = require("child_process");
|
|
17
|
+
const redis_smq_common_1 = require("redis-smq-common");
|
|
18
|
+
const path_1 = __importDefault(require("path"));
|
|
19
|
+
const config_js_1 = require("./config.js");
|
|
20
|
+
const supertest_1 = __importDefault(require("supertest"));
|
|
21
|
+
function startCliWithArgs(args) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
var _a, _b;
|
|
24
|
+
const node = process.execPath;
|
|
25
|
+
const currentDir = redis_smq_common_1.env.getCurrentDir();
|
|
26
|
+
const cliPath = path_1.default.resolve(currentDir, '../../bin/cli.js');
|
|
27
|
+
const port = yield redis_smq_common_1.net.getRandomPort();
|
|
28
|
+
const finalArgs = [
|
|
29
|
+
cliPath,
|
|
30
|
+
'--port',
|
|
31
|
+
String(port),
|
|
32
|
+
'--redis-port',
|
|
33
|
+
String((_b = (_a = config_js_1.config.redis) === null || _a === void 0 ? void 0 : _a.options) === null || _b === void 0 ? void 0 : _b.port),
|
|
34
|
+
...args,
|
|
35
|
+
];
|
|
36
|
+
const proc = (0, child_process_1.spawn)(node, finalArgs, {
|
|
37
|
+
env: Object.assign({}, process.env),
|
|
38
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
39
|
+
});
|
|
40
|
+
const stdout = [];
|
|
41
|
+
const stderr = [];
|
|
42
|
+
proc.stdout.on('data', (d) => stdout.push(String(d)));
|
|
43
|
+
proc.stderr.on('data', (d) => stderr.push(String(d)));
|
|
44
|
+
const url = `http://127.0.0.1:${port}`;
|
|
45
|
+
const deadline = Date.now() + 10000;
|
|
46
|
+
let lastErr;
|
|
47
|
+
while (Date.now() < deadline) {
|
|
48
|
+
try {
|
|
49
|
+
yield (0, supertest_1.default)(url).get('/').timeout({ deadline: 2000 });
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
catch (e) {
|
|
53
|
+
lastErr = e;
|
|
54
|
+
yield new Promise((r) => setTimeout(r, 150));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (Date.now() >= deadline) {
|
|
58
|
+
proc.kill('SIGKILL');
|
|
59
|
+
throw new Error(`CLI server did not start in time. stderr:\n${stderr.join('')}\nLastErr: ${String(lastErr)}`);
|
|
60
|
+
}
|
|
61
|
+
const stop = () => __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
proc.kill('SIGINT');
|
|
63
|
+
yield new Promise((r) => setTimeout(r, 200));
|
|
64
|
+
if (!proc.killed)
|
|
65
|
+
proc.kill('SIGKILL');
|
|
66
|
+
});
|
|
67
|
+
return { proc, url, stop, stdout, stderr };
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=start-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-cli.js","sourceRoot":"","sources":["../../../../tests/common/start-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test00002.test.d.ts","sourceRoot":"","sources":["../../../../tests/tests/test00002.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const vitest_1 = require("vitest");
|
|
16
|
+
const supertest_1 = __importDefault(require("supertest"));
|
|
17
|
+
const start_api_server_js_1 = require("../common/start-api-server.js");
|
|
18
|
+
const index_js_1 = require("../../index.js");
|
|
19
|
+
const config_js_1 = require("../common/config.js");
|
|
20
|
+
const redis_smq_common_1 = require("redis-smq-common");
|
|
21
|
+
(0, vitest_1.describe)('RedisSMQWebServer with apiProxyTarget', () => {
|
|
22
|
+
let webServerUrl;
|
|
23
|
+
let webServer;
|
|
24
|
+
(0, vitest_1.beforeEach)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
const apiPort = yield (0, start_api_server_js_1.startApiServer)();
|
|
26
|
+
const apiProxyTarget = `http://127.0.0.1:${apiPort}`;
|
|
27
|
+
const webServerPort = yield redis_smq_common_1.net.getRandomPort();
|
|
28
|
+
webServer = new index_js_1.RedisSMQWebServer(Object.assign(Object.assign({}, config_js_1.config), { webServer: {
|
|
29
|
+
port: webServerPort,
|
|
30
|
+
apiProxyTarget,
|
|
31
|
+
} }));
|
|
32
|
+
yield webServer.run();
|
|
33
|
+
webServerUrl = `http://127.0.0.1:${webServerPort}`;
|
|
34
|
+
}));
|
|
35
|
+
(0, vitest_1.afterEach)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
36
|
+
yield webServer.shutdown();
|
|
37
|
+
yield (0, start_api_server_js_1.stopApiServer)();
|
|
38
|
+
}));
|
|
39
|
+
(0, vitest_1.it)('proxies /api/v1 endpoints', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
40
|
+
yield (0, supertest_1.default)(webServerUrl)
|
|
41
|
+
.get('/api/v1/queues')
|
|
42
|
+
.expect(200)
|
|
43
|
+
.expect('Content-Type', /application\/json/);
|
|
44
|
+
}));
|
|
45
|
+
(0, vitest_1.it)('proxies /docs', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
46
|
+
const res = yield (0, supertest_1.default)(webServerUrl).get('/docs').expect(200);
|
|
47
|
+
(0, vitest_1.expect)(res.text).toContain('Swagger UI');
|
|
48
|
+
}));
|
|
49
|
+
(0, vitest_1.it)('serves SPA index.html for non-API routes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
50
|
+
const res = yield (0, supertest_1.default)(webServerUrl)
|
|
51
|
+
.get('/queues/my-queue')
|
|
52
|
+
.expect(200)
|
|
53
|
+
.expect('Content-Type', /text\/html/);
|
|
54
|
+
(0, vitest_1.expect)(res.text).toContain('<!doctype html>');
|
|
55
|
+
}));
|
|
56
|
+
(0, vitest_1.it)('serves assets as static files', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
57
|
+
const res = yield (0, supertest_1.default)(webServerUrl).get('/').expect(200);
|
|
58
|
+
const match = res.text.match(/<script[^>]+src=["']([^"']+)["']/i);
|
|
59
|
+
(0, vitest_1.expect)(match).toBeTruthy();
|
|
60
|
+
const scriptSrc = (match === null || match === void 0 ? void 0 : match[1]) || '';
|
|
61
|
+
const assetPath = scriptSrc.startsWith('http')
|
|
62
|
+
? scriptSrc.replace(webServerUrl, '')
|
|
63
|
+
: scriptSrc;
|
|
64
|
+
const assetRes = yield (0, supertest_1.default)(webServerUrl).get(assetPath).expect(200);
|
|
65
|
+
(0, vitest_1.expect)(assetRes.headers['cache-control']).toBeDefined();
|
|
66
|
+
}));
|
|
67
|
+
});
|
|
68
|
+
//# 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 @@
|
|
|
1
|
+
{"version":3,"file":"test00003.test.d.ts","sourceRoot":"","sources":["../../../../tests/tests/test00003.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const vitest_1 = require("vitest");
|
|
16
|
+
const supertest_1 = __importDefault(require("supertest"));
|
|
17
|
+
const start_api_server_js_1 = require("../common/start-api-server.js");
|
|
18
|
+
const start_cli_js_1 = require("../common/start-cli.js");
|
|
19
|
+
(0, vitest_1.describe)('RedisSMQ Web Server CLI e2e tests', () => {
|
|
20
|
+
(0, vitest_1.describe)('serves SPA with default basePath "/"', () => {
|
|
21
|
+
let started;
|
|
22
|
+
(0, vitest_1.beforeAll)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
23
|
+
started = yield (0, start_cli_js_1.startCliWithArgs)([
|
|
24
|
+
'--base-path',
|
|
25
|
+
'/',
|
|
26
|
+
'--enable-log',
|
|
27
|
+
'0',
|
|
28
|
+
]);
|
|
29
|
+
}));
|
|
30
|
+
(0, vitest_1.afterAll)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
31
|
+
yield started.stop();
|
|
32
|
+
}));
|
|
33
|
+
(0, vitest_1.it)('returns index.html for / and caches assets', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
34
|
+
var _a;
|
|
35
|
+
const res = yield (0, supertest_1.default)(started.url).get('/index.html').expect(200);
|
|
36
|
+
(0, vitest_1.expect)(res.headers['content-type']).toMatch(/text\/html/);
|
|
37
|
+
(0, vitest_1.expect)(res.headers['cache-control']).toMatch(/no-cache/);
|
|
38
|
+
const match = res.text.match(/<script[^>]+src=["']([^"']+)["']/i);
|
|
39
|
+
(0, vitest_1.expect)(match).toBeTruthy();
|
|
40
|
+
const scriptSrc = (_a = match === null || match === void 0 ? void 0 : match[1]) !== null && _a !== void 0 ? _a : '';
|
|
41
|
+
const assetPath = scriptSrc.startsWith('http')
|
|
42
|
+
? scriptSrc.replace(started.url, '')
|
|
43
|
+
: scriptSrc;
|
|
44
|
+
const assetRes = yield (0, supertest_1.default)(started.url).get(assetPath).expect(200);
|
|
45
|
+
(0, vitest_1.expect)(assetRes.headers['cache-control']).toBeDefined();
|
|
46
|
+
(0, vitest_1.expect)(assetRes.headers['cache-control']).toMatch(/max-age=\d+/);
|
|
47
|
+
}));
|
|
48
|
+
(0, vitest_1.it)('SPA fallback works on non-API route', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
49
|
+
const res = yield (0, supertest_1.default)(started.url).get('/queues/demo').expect(200);
|
|
50
|
+
(0, vitest_1.expect)(res.headers['content-type']).toMatch(/text\/html/);
|
|
51
|
+
}));
|
|
52
|
+
});
|
|
53
|
+
(0, vitest_1.describe)('respects custom basePath "/ui"', () => {
|
|
54
|
+
let started;
|
|
55
|
+
(0, vitest_1.beforeAll)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
56
|
+
started = yield (0, start_cli_js_1.startCliWithArgs)([
|
|
57
|
+
'--base-path',
|
|
58
|
+
'/ui',
|
|
59
|
+
'--enable-log',
|
|
60
|
+
'0',
|
|
61
|
+
]);
|
|
62
|
+
}));
|
|
63
|
+
(0, vitest_1.afterAll)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
64
|
+
yield started.stop();
|
|
65
|
+
}));
|
|
66
|
+
(0, vitest_1.it)('redirects "/" to "/ui"', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
67
|
+
const res = yield (0, supertest_1.default)(started.url).get('/').expect(302);
|
|
68
|
+
(0, vitest_1.expect)(res.headers.location).toBe('/ui');
|
|
69
|
+
}));
|
|
70
|
+
(0, vitest_1.it)('serves index.html at "/ui" and SPA fallback under it', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
71
|
+
const res = yield (0, supertest_1.default)(started.url).get('/ui').expect(200);
|
|
72
|
+
(0, vitest_1.expect)(res.headers['content-type']).toMatch(/text\/html/);
|
|
73
|
+
const sub = yield (0, supertest_1.default)(started.url).get('/ui/queues').expect(200);
|
|
74
|
+
(0, vitest_1.expect)(sub.headers['content-type']).toMatch(/text\/html/);
|
|
75
|
+
}));
|
|
76
|
+
(0, vitest_1.it)('serves api requests under custom basePath', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
77
|
+
yield (0, supertest_1.default)(started.url)
|
|
78
|
+
.get('/ui/api/v1/queues')
|
|
79
|
+
.expect((r) => {
|
|
80
|
+
(0, vitest_1.expect)(r.headers['content-type']).not.toMatch(/text\/html/);
|
|
81
|
+
});
|
|
82
|
+
}));
|
|
83
|
+
});
|
|
84
|
+
(0, vitest_1.describe)('proxies API when apiProxyTarget is set', () => {
|
|
85
|
+
let started;
|
|
86
|
+
(0, vitest_1.beforeAll)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
87
|
+
const port = yield (0, start_api_server_js_1.startApiServer)();
|
|
88
|
+
started = yield (0, start_cli_js_1.startCliWithArgs)([
|
|
89
|
+
'--base-path',
|
|
90
|
+
'/',
|
|
91
|
+
'--api-proxy-target',
|
|
92
|
+
`http://127.0.0.1:${port}`,
|
|
93
|
+
'--enable-log',
|
|
94
|
+
'0',
|
|
95
|
+
]);
|
|
96
|
+
}));
|
|
97
|
+
(0, vitest_1.afterAll)(() => __awaiter(void 0, void 0, void 0, function* () {
|
|
98
|
+
yield started.stop();
|
|
99
|
+
yield (0, start_api_server_js_1.stopApiServer)();
|
|
100
|
+
}));
|
|
101
|
+
(0, vitest_1.it)('proxies /api/v1 endpoints', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
102
|
+
yield (0, supertest_1.default)(started.url)
|
|
103
|
+
.get('/api/v1/queues')
|
|
104
|
+
.expect(200)
|
|
105
|
+
.expect('Content-Type', /application\/json/);
|
|
106
|
+
}));
|
|
107
|
+
(0, vitest_1.it)('proxies /docs', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
108
|
+
const res = yield (0, supertest_1.default)(started.url).get('/docs').expect(200);
|
|
109
|
+
(0, vitest_1.expect)(res.text).toMatch(/<html|<!doctype/i);
|
|
110
|
+
}));
|
|
111
|
+
(0, vitest_1.it)('keeps SPA behavior for non-API routes', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
112
|
+
const res = yield (0, supertest_1.default)(started.url).get('/about').expect(200);
|
|
113
|
+
(0, vitest_1.expect)(res.headers['content-type']).toMatch(/text\/html/);
|
|
114
|
+
}));
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
//# 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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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-api-server.d.ts","sourceRoot":"","sources":["../../../../tests/common/start-api-server.ts"],"names":[],"mappings":"AAeA,wBAAsB,cAAc,gCASnC;AAED,wBAAsB,aAAa,kBAKlC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { net } from 'redis-smq-common';
|
|
2
|
+
import { config } from './config.js';
|
|
3
|
+
import { RedisSMQRestApi } from 'redis-smq-rest-api';
|
|
4
|
+
let server = null;
|
|
5
|
+
export async function startApiServer() {
|
|
6
|
+
if (!server) {
|
|
7
|
+
const port = await net.getRandomPort();
|
|
8
|
+
config.apiServer = config.apiServer || {};
|
|
9
|
+
config.apiServer.port = port;
|
|
10
|
+
server = new RedisSMQRestApi(config);
|
|
11
|
+
await server.run();
|
|
12
|
+
return port;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export async function stopApiServer() {
|
|
16
|
+
if (server) {
|
|
17
|
+
await server.shutdown();
|
|
18
|
+
server = null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=start-api-server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-api-server.js","sourceRoot":"","sources":["../../../../tests/common/start-api-server.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AACvC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,IAAI,MAAM,GAA2B,IAAI,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,cAAc;IAClC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,aAAa,EAAE,CAAC;QACvC,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,IAAI,EAAE,CAAC;QAC1C,MAAM,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,CAAC;QAC7B,MAAM,GAAG,IAAI,eAAe,CAAC,MAAM,CAAC,CAAC;QACrC,MAAM,MAAM,CAAC,GAAG,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa;IACjC,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;QACxB,MAAM,GAAG,IAAI,CAAC;IAChB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
export type StartedProcess = {
|
|
3
|
+
proc: ReturnType<typeof spawn>;
|
|
4
|
+
url: string;
|
|
5
|
+
stop: () => Promise<void>;
|
|
6
|
+
stdout: string[];
|
|
7
|
+
stderr: string[];
|
|
8
|
+
};
|
|
9
|
+
export declare function startCliWithArgs(args: string[]): Promise<StartedProcess>;
|
|
10
|
+
//# sourceMappingURL=start-cli.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-cli.d.ts","sourceRoot":"","sources":["../../../../tests/common/start-cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AAMtC,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EAAE,GACb,OAAO,CAAC,cAAc,CAAC,CAyDzB"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { env, net } from 'redis-smq-common';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { config } from './config.js';
|
|
5
|
+
import request from 'supertest';
|
|
6
|
+
export async function startCliWithArgs(args) {
|
|
7
|
+
const node = process.execPath;
|
|
8
|
+
const currentDir = env.getCurrentDir();
|
|
9
|
+
const cliPath = path.resolve(currentDir, '../../bin/cli.js');
|
|
10
|
+
const port = await net.getRandomPort();
|
|
11
|
+
const finalArgs = [
|
|
12
|
+
cliPath,
|
|
13
|
+
'--port',
|
|
14
|
+
String(port),
|
|
15
|
+
'--redis-port',
|
|
16
|
+
String(config.redis?.options?.port),
|
|
17
|
+
...args,
|
|
18
|
+
];
|
|
19
|
+
const proc = spawn(node, finalArgs, {
|
|
20
|
+
env: {
|
|
21
|
+
...process.env,
|
|
22
|
+
},
|
|
23
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
24
|
+
});
|
|
25
|
+
const stdout = [];
|
|
26
|
+
const stderr = [];
|
|
27
|
+
proc.stdout.on('data', (d) => stdout.push(String(d)));
|
|
28
|
+
proc.stderr.on('data', (d) => stderr.push(String(d)));
|
|
29
|
+
const url = `http://127.0.0.1:${port}`;
|
|
30
|
+
const deadline = Date.now() + 10000;
|
|
31
|
+
let lastErr;
|
|
32
|
+
while (Date.now() < deadline) {
|
|
33
|
+
try {
|
|
34
|
+
await request(url).get('/').timeout({ deadline: 2000 });
|
|
35
|
+
break;
|
|
36
|
+
}
|
|
37
|
+
catch (e) {
|
|
38
|
+
lastErr = e;
|
|
39
|
+
await new Promise((r) => setTimeout(r, 150));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (Date.now() >= deadline) {
|
|
43
|
+
proc.kill('SIGKILL');
|
|
44
|
+
throw new Error(`CLI server did not start in time. stderr:\n${stderr.join('')}\nLastErr: ${String(lastErr)}`);
|
|
45
|
+
}
|
|
46
|
+
const stop = async () => {
|
|
47
|
+
proc.kill('SIGINT');
|
|
48
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
49
|
+
if (!proc.killed)
|
|
50
|
+
proc.kill('SIGKILL');
|
|
51
|
+
};
|
|
52
|
+
return { proc, url, stop, stdout, stderr };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=start-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start-cli.js","sourceRoot":"","sources":["../../../../tests/common/start-cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -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 @@
|
|
|
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.
|
|
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",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"@redis/client": "^5",
|
|
48
48
|
"ioredis": "^5",
|
|
49
|
-
"redis-smq": "^9.0.0-next.
|
|
50
|
-
"redis-smq-
|
|
51
|
-
"redis-smq-
|
|
52
|
-
"redis-smq
|
|
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
53
|
},
|
|
54
54
|
"peerDependenciesMeta": {
|
|
55
55
|
"@redis/client": {
|