@bull-board/cli 0.0.0 → 9.3.0

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 (57) hide show
  1. package/README.md +69 -0
  2. package/dist/auth.d.ts +5 -0
  3. package/dist/auth.js +29 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/bin.d.ts +2 -0
  6. package/dist/bin.js +69 -0
  7. package/dist/bin.js.map +1 -0
  8. package/dist/config/file.d.ts +9 -0
  9. package/dist/config/file.js +82 -0
  10. package/dist/config/file.js.map +1 -0
  11. package/dist/config/flags.d.ts +77 -0
  12. package/dist/config/flags.js +29 -0
  13. package/dist/config/flags.js.map +1 -0
  14. package/dist/config/resolve.d.ts +7 -0
  15. package/dist/config/resolve.js +73 -0
  16. package/dist/config/resolve.js.map +1 -0
  17. package/dist/config/types.d.ts +36 -0
  18. package/dist/config/types.js +3 -0
  19. package/dist/config/types.js.map +1 -0
  20. package/dist/connectionState.d.ts +21 -0
  21. package/dist/connectionState.js +28 -0
  22. package/dist/connectionState.js.map +1 -0
  23. package/dist/describeError.d.ts +1 -0
  24. package/dist/describeError.js +12 -0
  25. package/dist/describeError.js.map +1 -0
  26. package/dist/diagnosticPage.d.ts +3 -0
  27. package/dist/diagnosticPage.js +150 -0
  28. package/dist/diagnosticPage.js.map +1 -0
  29. package/dist/discovery/index.d.ts +9 -0
  30. package/dist/discovery/index.js +63 -0
  31. package/dist/discovery/index.js.map +1 -0
  32. package/dist/discovery/scan.d.ts +2 -0
  33. package/dist/discovery/scan.js +12 -0
  34. package/dist/discovery/scan.js.map +1 -0
  35. package/dist/help.d.ts +1 -0
  36. package/dist/help.js +48 -0
  37. package/dist/help.js.map +1 -0
  38. package/dist/index.d.ts +10 -0
  39. package/dist/index.js +238 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/openBrowser.d.ts +1 -0
  42. package/dist/openBrowser.js +46 -0
  43. package/dist/openBrowser.js.map +1 -0
  44. package/dist/queueFactory.d.ts +15 -0
  45. package/dist/queueFactory.js +63 -0
  46. package/dist/queueFactory.js.map +1 -0
  47. package/dist/registry.d.ts +22 -0
  48. package/dist/registry.js +61 -0
  49. package/dist/registry.js.map +1 -0
  50. package/dist/server.d.ts +14 -0
  51. package/dist/server.js +34 -0
  52. package/dist/server.js.map +1 -0
  53. package/dist/unavailableGate.d.ts +8 -0
  54. package/dist/unavailableGate.js +37 -0
  55. package/dist/unavailableGate.js.map +1 -0
  56. package/package.json +57 -4
  57. package/index.js +0 -1
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # @bull-board/cli
2
+
3
+ Run the [bull-board](https://github.com/felixmosh/bull-board) dashboard against a Redis instance, no app to wire it into.
4
+
5
+ ```sh
6
+ npx @bull-board/cli -r redis://localhost:6379
7
+ ```
8
+
9
+ That opens `http://127.0.0.1:3000` with the dashboard for every Bull and BullMQ queue it finds under the `bull` key prefix.
10
+
11
+ ![bull-board dashboard](https://raw.githubusercontent.com/felixmosh/bull-board/master/website/docs/public/screenshots/dashboard-overview.png)
12
+
13
+ ## When you'd reach for this
14
+
15
+ - The workers live in a repo or a container you are not editing, and you want to watch jobs move without adding a route to an app you would then have to remember to remove.
16
+ - Your producers are not Node. BullMQ has an official Python package and gets written to over the raw protocol from other languages. Those teams have no app to embed the dashboard into.
17
+ - You want to look at a queue on staging or production through a tunnel, without deploying anything.
18
+ - You are evaluating bull-board and would rather see your own queues than wire up an integration first.
19
+
20
+ This is not a replacement for mounting an adapter in your own server: there's no auto-login, no framework-level auth to inherit, and every option has to be passed on the command line, an env var, or a config file instead of code.
21
+
22
+ ## Options
23
+
24
+ ```
25
+ Usage:
26
+ bull-board [options]
27
+ npx @bull-board/cli [options]
28
+
29
+ Options:
30
+ -r, --redis <url> Redis connection URL [redis://localhost:6379]
31
+ -p, --port <port> Port to listen on [3000]
32
+ --host <address> Interface to bind [127.0.0.1]
33
+ --prefix <list> Comma separated key prefixes [bull]
34
+ --queues <list> Use these queue names instead of discovering
35
+ --scan-interval <s> Seconds between rescans, 0 to scan once [10]
36
+ --base-path <path> Serve the dashboard under a path prefix
37
+ --read-only Disable every destructive action
38
+ --user <name> Basic auth user (requires --password)
39
+ --password <pass> Basic auth password (requires --user)
40
+ --board-title <s> Dashboard title
41
+ --config <file> Path to a config file
42
+ --browser <command> Command to open the browser with [$BROWSER]
43
+ --no-open Do not open a browser
44
+ --no-retry Exit if Redis is unreachable instead of retrying
45
+ -h, --help Show this help
46
+ -v, --version Show the version
47
+ ```
48
+
49
+ Every flag also has an environment variable equivalent (`BULL_BOARD_REDIS_URL`, `BULL_BOARD_PORT`, `BULL_BOARD_READ_ONLY`, and so on), and a `bull-board.config.{mjs,js,cjs,json}` file for anything that doesn't fit on a command line. Flags win over environment variables, which win over the config file, which wins over the built-in default.
50
+
51
+ If Redis is unreachable when the CLI starts, it still opens: it serves a diagnostic page explaining why (the URL it dialled, the underlying error, and the likely causes), keeps retrying every 3 seconds, and switches to the real dashboard on its own the moment Redis answers, no restart needed. That only covers startup, though: once the dashboard is live it stays live, even if Redis later goes away. The diagnostic page does not come back; API requests just stop returning until Redis is reachable again, and Ctrl-C still works. Pass `--no-retry` for the old behaviour instead: print the error and exit 1 immediately, without ever opening a port, which is what a script or CI checking the exit code wants.
52
+
53
+ ```js
54
+ // bull-board.config.js
55
+ module.exports = {
56
+ redis: 'redis://localhost:6379',
57
+ prefix: ['bull', 'tenant-a'],
58
+ uiConfig: {
59
+ boardTitle: 'Ops Dashboard',
60
+ },
61
+ queues: {
62
+ 'payment-webhooks': { readOnlyMode: true },
63
+ },
64
+ };
65
+ ```
66
+
67
+ Discovery only reads Redis, so BullMQ v6 queues backed by PostgreSQL aren't found here; use a server adapter in your own app for those. `--prefix` doesn't take wildcards either, list the prefixes you need explicitly.
68
+
69
+ See the [CLI guide](https://felixmosh.github.io/bull-board/guide/cli) for the full flag and environment variable reference, a Docker Compose example, and the basic auth walkthrough.
package/dist/auth.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import type { RequestHandler } from 'express';
2
+ export declare function basicAuth({ user, password }: {
3
+ user: string;
4
+ password: string;
5
+ }): RequestHandler;
package/dist/auth.js ADDED
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.basicAuth = basicAuth;
4
+ const node_crypto_1 = require("node:crypto");
5
+ // timingSafeEqual needs equal lengths, so the length comparison is folded into the answer.
6
+ function timingSafeCompare(supplied, expected) {
7
+ const suppliedBytes = Buffer.from(supplied, 'utf8');
8
+ const expectedBytes = Buffer.from(expected, 'utf8');
9
+ const sameLength = suppliedBytes.length === expectedBytes.length;
10
+ const target = sameLength ? expectedBytes : suppliedBytes;
11
+ return (0, node_crypto_1.timingSafeEqual)(suppliedBytes, target) && sameLength;
12
+ }
13
+ function basicAuth({ user, password }) {
14
+ const expected = `${user}:${password}`;
15
+ return (req, res, next) => {
16
+ const header = req.headers.authorization || '';
17
+ const [scheme, encoded] = header.split(' ');
18
+ if ((scheme === null || scheme === void 0 ? void 0 : scheme.toLowerCase()) === 'basic' && encoded) {
19
+ const supplied = Buffer.from(encoded, 'base64').toString('utf8');
20
+ if (timingSafeCompare(supplied, expected)) {
21
+ next();
22
+ return;
23
+ }
24
+ }
25
+ res.setHeader('WWW-Authenticate', 'Basic realm="bull-board"');
26
+ res.status(401).send('Unauthorized');
27
+ };
28
+ }
29
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":";;AAaA,8BAmBC;AAhCD,6CAA8C;AAG9C,2FAA2F;AAC3F,SAAS,iBAAiB,CAAC,QAAgB,EAAE,QAAgB;IAC3D,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,KAAK,aAAa,CAAC,MAAM,CAAC;IACjE,MAAM,MAAM,GAAG,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;IAE1D,OAAO,IAAA,6BAAe,EAAC,aAAa,EAAE,MAAM,CAAC,IAAI,UAAU,CAAC;AAC9D,CAAC;AAED,SAAgB,SAAS,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAsC;IAC9E,MAAM,QAAQ,GAAG,GAAG,IAAI,IAAI,QAAQ,EAAE,CAAC;IAEvC,OAAO,CAAC,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,EAAE;QACxB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC;QAC/C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAE5C,IAAI,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,WAAW,EAAE,MAAK,OAAO,IAAI,OAAO,EAAE,CAAC;YACjD,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAEjE,IAAI,iBAAiB,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC;gBAC1C,IAAI,EAAE,CAAC;gBACP,OAAO;YACT,CAAC;QACH,CAAC;QAED,GAAG,CAAC,SAAS,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAC;QAC9D,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACvC,CAAC,CAAC;AACJ,CAAC"}
package/dist/bin.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/bin.js ADDED
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ const file_1 = require("./config/file");
5
+ const flags_1 = require("./config/flags");
6
+ const resolve_1 = require("./config/resolve");
7
+ const help_1 = require("./help");
8
+ const index_1 = require("./index");
9
+ const openBrowser_1 = require("./openBrowser");
10
+ async function main() {
11
+ let flags;
12
+ try {
13
+ flags = (0, flags_1.parseFlags)(process.argv.slice(2));
14
+ }
15
+ catch (error) {
16
+ throw new Error(`${error.message}\nRun bull-board --help for usage.`);
17
+ }
18
+ if (flags.help) {
19
+ // oxlint-disable-next-line no-console
20
+ console.log(help_1.HELP);
21
+ return;
22
+ }
23
+ if (flags.version) {
24
+ // oxlint-disable-next-line no-console
25
+ console.log(require('../package.json').version);
26
+ return;
27
+ }
28
+ const file = await (0, file_1.loadConfigFile)({
29
+ cwd: process.cwd(),
30
+ explicitPath: flags.config || process.env.BULL_BOARD_CONFIG,
31
+ });
32
+ const config = (0, resolve_1.resolveConfig)({ flags, env: process.env, file });
33
+ if (!config.redisUrl.startsWith('/')) {
34
+ let parsed;
35
+ try {
36
+ parsed = new URL(config.redisUrl);
37
+ }
38
+ catch {
39
+ throw new Error(`Invalid Redis URL: ${config.redisUrl}`);
40
+ }
41
+ if (!['redis:', 'rediss:'].includes(parsed.protocol)) {
42
+ throw new Error(`Redis URL must use redis:// or rediss://, got "${parsed.protocol}//"`);
43
+ }
44
+ }
45
+ const board = await (0, index_1.run)(config, console, {
46
+ beforeReady: (close) => {
47
+ for (const signal of ['SIGINT', 'SIGTERM']) {
48
+ process.once(signal, () => {
49
+ // oxlint-disable-next-line no-console
50
+ console.log('\nShutting down.');
51
+ close()
52
+ .then(() => process.exit(0))
53
+ .catch((error) => {
54
+ console.error(error.message);
55
+ process.exit(1);
56
+ });
57
+ });
58
+ }
59
+ },
60
+ });
61
+ if (config.open) {
62
+ (0, openBrowser_1.openBrowser)(board.url, config.browser);
63
+ }
64
+ }
65
+ main().catch((error) => {
66
+ console.error(error.message);
67
+ process.exit(1);
68
+ });
69
+ //# sourceMappingURL=bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { FileConfig } from './types';
2
+ export type ImportModule = (specifier: string) => Promise<{
3
+ default?: unknown;
4
+ }>;
5
+ export declare function loadConfigFile({ cwd, explicitPath, importModule, }: {
6
+ cwd: string;
7
+ explicitPath?: string;
8
+ importModule?: ImportModule;
9
+ }): Promise<FileConfig>;
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.loadConfigFile = loadConfigFile;
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
+ const node_url_1 = require("node:url");
7
+ const CANDIDATES = [
8
+ 'bull-board.config.mjs',
9
+ 'bull-board.config.js',
10
+ 'bull-board.config.cjs',
11
+ 'bull-board.config.json',
12
+ ];
13
+ // tsc compiles a bare `import()` down to `require()` under module: CommonJS, which cannot
14
+ // load an ESM config file. Hiding it behind `new Function` keeps a real dynamic import in
15
+ // the emitted JavaScript.
16
+ const dynamicImport = new Function('specifier', 'return import(specifier)');
17
+ async function loadConfigFile({ cwd, explicitPath, importModule = dynamicImport, }) {
18
+ var _a;
19
+ const path = explicitPath
20
+ ? (0, node_path_1.isAbsolute)(explicitPath)
21
+ ? explicitPath
22
+ : (0, node_path_1.resolve)(cwd, explicitPath)
23
+ : CANDIDATES.map((name) => (0, node_path_1.join)(cwd, name)).find((candidate) => (0, node_fs_1.existsSync)(candidate));
24
+ if (!path) {
25
+ return {};
26
+ }
27
+ if (explicitPath && !(0, node_fs_1.existsSync)(path)) {
28
+ throw new Error(`Config file not found: ${path}`);
29
+ }
30
+ let config;
31
+ if (path.endsWith('.json')) {
32
+ try {
33
+ config = JSON.parse((0, node_fs_1.readFileSync)(path, 'utf8'));
34
+ }
35
+ catch (error) {
36
+ throw new Error(`Could not parse ${path}: ${error.message}`);
37
+ }
38
+ }
39
+ else {
40
+ const loaded = await loadModule(path, importModule);
41
+ config = (_a = loaded.default) !== null && _a !== void 0 ? _a : loaded;
42
+ }
43
+ if (typeof config !== 'object' || config === null || Array.isArray(config)) {
44
+ throw new Error(`Config file ${path} must export an object.`);
45
+ }
46
+ return config;
47
+ }
48
+ /**
49
+ * `.mjs` is always ESM and needs a real dynamic import. `.js` and `.cjs` are CommonJS in
50
+ * the common case, and `require` reads them in every context, including test sandboxes
51
+ * that cannot run a dynamic import. A `.js` file in a `"type": "module"` project is ESM
52
+ * even so, which is what the fallback is for.
53
+ */
54
+ async function loadModule(path, importModule) {
55
+ const url = (0, node_url_1.pathToFileURL)(path).href;
56
+ if (path.endsWith('.mjs')) {
57
+ return importModule(url);
58
+ }
59
+ try {
60
+ return require(path);
61
+ }
62
+ catch (error) {
63
+ if (!isEsmLoadError(error))
64
+ throw error;
65
+ return importModule(url);
66
+ }
67
+ }
68
+ /**
69
+ * Only an ESM file reached through `require` may be retried as a dynamic import. Any other
70
+ * failure is the config file's own bug, and swallowing it would both hide the real error
71
+ * and run the file's side effects a second time.
72
+ *
73
+ * Node reports this as `ERR_REQUIRE_ESM`, but a transpiling test sandbox reports the same
74
+ * situation as a plain syntax error, so both shapes count.
75
+ */
76
+ function isEsmLoadError(error) {
77
+ const { code, message = '' } = (error || {});
78
+ return (code === 'ERR_REQUIRE_ESM' ||
79
+ message.includes('Cannot use import statement outside a module') ||
80
+ message.includes(`Unexpected token 'export'`));
81
+ }
82
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/config/file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,77 @@
1
+ export declare const FLAG_OPTIONS: {
2
+ readonly redis: {
3
+ readonly type: "string";
4
+ readonly short: "r";
5
+ };
6
+ readonly port: {
7
+ readonly type: "string";
8
+ readonly short: "p";
9
+ };
10
+ readonly host: {
11
+ readonly type: "string";
12
+ };
13
+ readonly prefix: {
14
+ readonly type: "string";
15
+ };
16
+ readonly queues: {
17
+ readonly type: "string";
18
+ };
19
+ readonly 'scan-interval': {
20
+ readonly type: "string";
21
+ };
22
+ readonly 'base-path': {
23
+ readonly type: "string";
24
+ };
25
+ readonly 'read-only': {
26
+ readonly type: "boolean";
27
+ };
28
+ readonly user: {
29
+ readonly type: "string";
30
+ };
31
+ readonly password: {
32
+ readonly type: "string";
33
+ };
34
+ readonly 'board-title': {
35
+ readonly type: "string";
36
+ };
37
+ readonly config: {
38
+ readonly type: "string";
39
+ };
40
+ readonly 'no-open': {
41
+ readonly type: "boolean";
42
+ };
43
+ readonly 'no-retry': {
44
+ readonly type: "boolean";
45
+ };
46
+ readonly help: {
47
+ readonly type: "boolean";
48
+ readonly short: "h";
49
+ };
50
+ readonly version: {
51
+ readonly type: "boolean";
52
+ readonly short: "v";
53
+ };
54
+ readonly browser: {
55
+ readonly type: "string";
56
+ };
57
+ };
58
+ export declare function parseFlags(argv: string[]): {
59
+ redis?: string | undefined;
60
+ port?: string | undefined;
61
+ host?: string | undefined;
62
+ prefix?: string | undefined;
63
+ queues?: string | undefined;
64
+ 'scan-interval'?: string | undefined;
65
+ 'base-path'?: string | undefined;
66
+ 'read-only'?: boolean | undefined;
67
+ user?: string | undefined;
68
+ password?: string | undefined;
69
+ 'board-title'?: string | undefined;
70
+ config?: string | undefined;
71
+ 'no-open'?: boolean | undefined;
72
+ 'no-retry'?: boolean | undefined;
73
+ help?: boolean | undefined;
74
+ version?: boolean | undefined;
75
+ browser?: string | undefined;
76
+ };
77
+ export type FlagValues = ReturnType<typeof parseFlags>;
@@ -0,0 +1,29 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FLAG_OPTIONS = void 0;
4
+ exports.parseFlags = parseFlags;
5
+ const node_util_1 = require("node:util");
6
+ exports.FLAG_OPTIONS = {
7
+ redis: { type: 'string', short: 'r' },
8
+ port: { type: 'string', short: 'p' },
9
+ host: { type: 'string' },
10
+ prefix: { type: 'string' },
11
+ queues: { type: 'string' },
12
+ 'scan-interval': { type: 'string' },
13
+ 'base-path': { type: 'string' },
14
+ 'read-only': { type: 'boolean' },
15
+ user: { type: 'string' },
16
+ password: { type: 'string' },
17
+ 'board-title': { type: 'string' },
18
+ config: { type: 'string' },
19
+ 'no-open': { type: 'boolean' },
20
+ 'no-retry': { type: 'boolean' },
21
+ help: { type: 'boolean', short: 'h' },
22
+ version: { type: 'boolean', short: 'v' },
23
+ browser: { type: 'string' },
24
+ };
25
+ function parseFlags(argv) {
26
+ const { values } = (0, node_util_1.parseArgs)({ args: argv, options: exports.FLAG_OPTIONS, allowPositionals: false });
27
+ return values;
28
+ }
29
+ //# sourceMappingURL=flags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flags.js","sourceRoot":"","sources":["../../src/config/flags.ts"],"names":[],"mappings":";;;AAsBA,gCAIC;AA1BD,yCAAsC;AAEzB,QAAA,YAAY,GAAG;IAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;IACrC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,EAAE;IACpC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACxB,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC1B,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC1B,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACnC,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC/B,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAChC,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACxB,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC5B,aAAa,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IACjC,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;IAC1B,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE;IAC/B,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;IACrC,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE;IACxC,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;CACnB,CAAC;AAEX,SAAgB,UAAU,CAAC,IAAc;IACvC,MAAM,EAAE,MAAM,EAAE,GAAG,IAAA,qBAAS,EAAC,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,oBAAY,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC,CAAC;IAE7F,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { FlagValues } from './flags';
2
+ import type { CliConfig, FileConfig } from './types';
3
+ export declare function resolveConfig({ flags, env, file, }: {
4
+ flags: FlagValues;
5
+ env: NodeJS.ProcessEnv;
6
+ file: FileConfig;
7
+ }): CliConfig;
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.resolveConfig = resolveConfig;
4
+ const DEFAULTS = {
5
+ redisUrl: 'redis://localhost:6379',
6
+ port: 3000,
7
+ host: '127.0.0.1',
8
+ prefixes: ['bull'],
9
+ scanInterval: 10,
10
+ };
11
+ function firstDefined(...values) {
12
+ return values.find((value) => value !== undefined && value !== '');
13
+ }
14
+ function toList(value) {
15
+ if (value === undefined)
16
+ return undefined;
17
+ const parts = (Array.isArray(value) ? value : value.split(','))
18
+ .map((part) => part.trim())
19
+ .filter(Boolean);
20
+ return parts.length > 0 ? parts : undefined;
21
+ }
22
+ function toNumber(value, label) {
23
+ if (value === undefined)
24
+ return undefined;
25
+ const parsed = typeof value === 'number' ? value : Number(value);
26
+ if (!Number.isFinite(parsed)) {
27
+ throw new Error(`Invalid ${label}: ${value}`);
28
+ }
29
+ return parsed;
30
+ }
31
+ function toBoolean(value) {
32
+ if (value === undefined)
33
+ return undefined;
34
+ return !['0', 'false', 'no', ''].includes(value.toLowerCase());
35
+ }
36
+ function normalizeBasePath(value) {
37
+ if (value === undefined)
38
+ return undefined;
39
+ const trimmed = value.replace(/^\/+|\/+$/g, '');
40
+ return trimmed === '' ? '' : `/${trimmed}`;
41
+ }
42
+ function resolveConfig({ flags, env, file, }) {
43
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0;
44
+ const explicitQueues = Array.isArray(file.queues) ? file.queues : undefined;
45
+ const queueOptions = (file.queues && !Array.isArray(file.queues) ? file.queues : {});
46
+ const user = firstDefined(flags.user, env.BULL_BOARD_USER, file.user);
47
+ const password = firstDefined(flags.password, env.BULL_BOARD_PASSWORD, file.password);
48
+ if (Boolean(user) !== Boolean(password)) {
49
+ throw new Error('Basic auth needs both --user and --password (or neither).');
50
+ }
51
+ const uiConfig = { ...file.uiConfig };
52
+ const boardTitle = firstDefined(flags['board-title'], env.BULL_BOARD_BOARD_TITLE);
53
+ if (boardTitle) {
54
+ uiConfig.boardTitle = boardTitle;
55
+ }
56
+ return {
57
+ redisUrl: (_a = firstDefined(flags.redis, env.BULL_BOARD_REDIS_URL, file.redis)) !== null && _a !== void 0 ? _a : DEFAULTS.redisUrl,
58
+ port: (_d = (_c = (_b = toNumber(flags.port, 'port')) !== null && _b !== void 0 ? _b : toNumber(env.BULL_BOARD_PORT, 'port')) !== null && _c !== void 0 ? _c : toNumber(file.port, 'port')) !== null && _d !== void 0 ? _d : DEFAULTS.port,
59
+ host: (_e = firstDefined(flags.host, env.BULL_BOARD_HOST, file.host)) !== null && _e !== void 0 ? _e : DEFAULTS.host,
60
+ prefixes: (_h = (_g = (_f = toList(flags.prefix)) !== null && _f !== void 0 ? _f : toList(env.BULL_BOARD_PREFIX)) !== null && _g !== void 0 ? _g : toList(file.prefix)) !== null && _h !== void 0 ? _h : DEFAULTS.prefixes,
61
+ queueNames: (_l = (_k = (_j = toList(flags.queues)) !== null && _j !== void 0 ? _j : toList(env.BULL_BOARD_QUEUES)) !== null && _k !== void 0 ? _k : toList(explicitQueues)) !== null && _l !== void 0 ? _l : null,
62
+ scanInterval: (_p = (_o = (_m = toNumber(flags['scan-interval'], 'scan-interval')) !== null && _m !== void 0 ? _m : toNumber(env.BULL_BOARD_SCAN_INTERVAL, 'scan-interval')) !== null && _o !== void 0 ? _o : toNumber(file.scanInterval, 'scan-interval')) !== null && _p !== void 0 ? _p : DEFAULTS.scanInterval,
63
+ basePath: (_s = (_r = (_q = normalizeBasePath(flags['base-path'])) !== null && _q !== void 0 ? _q : normalizeBasePath(env.BULL_BOARD_BASE_PATH)) !== null && _r !== void 0 ? _r : normalizeBasePath(file.basePath)) !== null && _s !== void 0 ? _s : '',
64
+ readOnly: (_v = (_u = (_t = flags['read-only']) !== null && _t !== void 0 ? _t : toBoolean(env.BULL_BOARD_READ_ONLY)) !== null && _u !== void 0 ? _u : file.readOnly) !== null && _v !== void 0 ? _v : false,
65
+ auth: user && password ? { user, password } : null,
66
+ open: flags['no-open'] === true ? false : ((_x = (_w = toBoolean(env.BULL_BOARD_OPEN)) !== null && _w !== void 0 ? _w : file.open) !== null && _x !== void 0 ? _x : true),
67
+ browser: firstDefined(flags.browser, env.BULL_BOARD_BROWSER, env.BROWSER, file.browser),
68
+ uiConfig,
69
+ queueOptions,
70
+ noRetry: (_0 = (_z = (_y = flags['no-retry']) !== null && _y !== void 0 ? _y : toBoolean(env.BULL_BOARD_NO_RETRY)) !== null && _z !== void 0 ? _z : file.noRetry) !== null && _0 !== void 0 ? _0 : false,
71
+ };
72
+ }
73
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/config/resolve.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { QueueAdapterOptions, UIConfig } from '@bull-board/api/typings/app';
2
+ export interface FileConfig {
3
+ redis?: string;
4
+ port?: number;
5
+ host?: string;
6
+ prefix?: string | string[];
7
+ queues?: string[] | Record<string, Partial<QueueAdapterOptions>>;
8
+ scanInterval?: number;
9
+ basePath?: string;
10
+ readOnly?: boolean;
11
+ user?: string;
12
+ password?: string;
13
+ open?: boolean;
14
+ browser?: string;
15
+ uiConfig?: UIConfig;
16
+ noRetry?: boolean;
17
+ }
18
+ export interface CliConfig {
19
+ redisUrl: string;
20
+ port: number;
21
+ host: string;
22
+ prefixes: string[];
23
+ queueNames: string[] | null;
24
+ scanInterval: number;
25
+ basePath: string;
26
+ readOnly: boolean;
27
+ auth: {
28
+ user: string;
29
+ password: string;
30
+ } | null;
31
+ open: boolean;
32
+ browser?: string;
33
+ uiConfig: UIConfig;
34
+ queueOptions: Record<string, Partial<QueueAdapterOptions>>;
35
+ noRetry: boolean;
36
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/config/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ export declare const RETRY_INTERVAL_MS = 3000;
2
+ export type ConnectionState = {
3
+ status: 'connecting';
4
+ redisUrl: string;
5
+ attempts: number;
6
+ } | {
7
+ status: 'connected';
8
+ redisUrl: string;
9
+ attempts: number;
10
+ } | {
11
+ status: 'unavailable';
12
+ redisUrl: string;
13
+ attempts: number;
14
+ lastError: string;
15
+ } | {
16
+ status: 'degraded';
17
+ redisUrl: string;
18
+ attempts: number;
19
+ lastError: string;
20
+ };
21
+ export declare function maskRedisUrl(redisUrl: string): string;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RETRY_INTERVAL_MS = void 0;
4
+ exports.maskRedisUrl = maskRedisUrl;
5
+ exports.RETRY_INTERVAL_MS = 3000;
6
+ function maskRedisUrl(redisUrl) {
7
+ if (redisUrl.startsWith('/'))
8
+ return redisUrl;
9
+ try {
10
+ const parsed = new URL(redisUrl);
11
+ let changed = false;
12
+ if (parsed.password) {
13
+ parsed.password = '***';
14
+ changed = true;
15
+ }
16
+ for (const key of ['password', 'auth']) {
17
+ if (parsed.searchParams.has(key)) {
18
+ parsed.searchParams.set(key, '***');
19
+ changed = true;
20
+ }
21
+ }
22
+ return changed ? parsed.toString() : redisUrl;
23
+ }
24
+ catch {
25
+ return redisUrl;
26
+ }
27
+ }
28
+ //# sourceMappingURL=connectionState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connectionState.js","sourceRoot":"","sources":["../src/connectionState.ts"],"names":[],"mappings":";;;AAQA,oCAuBC;AA/BY,QAAA,iBAAiB,GAAG,IAAI,CAAC;AAQtC,SAAgB,YAAY,CAAC,QAAgB;IAC3C,IAAI,QAAQ,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAE9C,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,IAAI,MAAM,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,CAAC,QAAQ,GAAG,KAAK,CAAC;YACxB,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,EAAE,CAAC;YACvC,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACpC,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1 @@
1
+ export declare function describeError(error: Error): string;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.describeError = describeError;
4
+ function describeError(error) {
5
+ if (error.message)
6
+ return error.message;
7
+ const causes = error.errors;
8
+ return Array.isArray(causes) && causes.length > 0
9
+ ? causes.map((cause) => cause.message).join('; ')
10
+ : String(error);
11
+ }
12
+ //# sourceMappingURL=describeError.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describeError.js","sourceRoot":"","sources":["../src/describeError.ts"],"names":[],"mappings":";;AAAA,sCAOC;AAPD,SAAgB,aAAa,CAAC,KAAY;IACxC,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC;IACxC,MAAM,MAAM,GAAI,KAA8B,CAAC,MAAM,CAAC;IAEtD,OAAO,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC;QAC/C,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAE,KAAe,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAC5D,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ConnectionState } from './connectionState';
2
+ export declare const STATUS_PATH = "/__bull-board-cli/status";
3
+ export declare function renderDiagnosticPage(state: ConnectionState): string;