bunqueue 2.8.38 → 2.8.40

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 (64) hide show
  1. package/dist/application/backgroundTasks.js +9 -0
  2. package/dist/application/cleanupTasks.js +31 -11
  3. package/dist/application/contextFactory.d.ts +3 -0
  4. package/dist/application/contextFactory.js +6 -0
  5. package/dist/application/dependencyResultTracker.d.ts +17 -0
  6. package/dist/application/dependencyResultTracker.js +71 -0
  7. package/dist/application/operations/ack.d.ts +2 -0
  8. package/dist/application/operations/ack.js +6 -0
  9. package/dist/application/operations/ackHelpers.d.ts +2 -1
  10. package/dist/application/operations/ackHelpers.js +6 -0
  11. package/dist/application/operations/jobManagement.d.ts +2 -0
  12. package/dist/application/operations/jobManagement.js +10 -4
  13. package/dist/application/operations/jobStateTransitions.js +1 -0
  14. package/dist/application/operations/pull.d.ts +2 -2
  15. package/dist/application/operations/pull.js +43 -10
  16. package/dist/application/operations/push.d.ts +2 -0
  17. package/dist/application/operations/pushInsert.d.ts +4 -0
  18. package/dist/application/operations/pushInsert.js +6 -0
  19. package/dist/application/operations/queryOperations.d.ts +2 -0
  20. package/dist/application/operations/queryOperations.js +5 -1
  21. package/dist/application/operations/queueControl.d.ts +2 -0
  22. package/dist/application/operations/queueControl.js +4 -0
  23. package/dist/application/queueManager.d.ts +5 -4
  24. package/dist/application/queueManager.js +37 -11
  25. package/dist/application/types.d.ts +2 -0
  26. package/dist/cli/client.js +6 -47
  27. package/dist/cli/commandRegistry.d.ts +27 -0
  28. package/dist/cli/commandRegistry.js +40 -0
  29. package/dist/cli/commandRouter.d.ts +3 -0
  30. package/dist/cli/commandRouter.js +44 -0
  31. package/dist/cli/commands/backup.js +1 -1
  32. package/dist/cli/commands/core.js +54 -2
  33. package/dist/cli/commands/doctor.d.ts +50 -5
  34. package/dist/cli/commands/doctor.js +125 -108
  35. package/dist/cli/commands/types.js +5 -1
  36. package/dist/cli/globalOptions.d.ts +16 -0
  37. package/dist/cli/globalOptions.js +192 -0
  38. package/dist/cli/help.d.ts +9 -0
  39. package/dist/cli/help.js +42 -21
  40. package/dist/cli/index.d.ts +1 -25
  41. package/dist/cli/index.js +84 -348
  42. package/dist/cli/localOutput.d.ts +22 -0
  43. package/dist/cli/localOutput.js +45 -0
  44. package/dist/client/queue/dlqOps.js +1 -3
  45. package/dist/client/tcp/client.js +10 -8
  46. package/dist/domain/queue/shard.d.ts +2 -2
  47. package/dist/domain/queue/shard.js +3 -3
  48. package/dist/domain/queue/waiterManager.d.ts +2 -2
  49. package/dist/domain/queue/waiterManager.js +26 -5
  50. package/dist/infrastructure/cloud/wsSender.js +4 -4
  51. package/dist/infrastructure/persistence/schema.d.ts +2 -2
  52. package/dist/infrastructure/persistence/schema.js +7 -2
  53. package/dist/infrastructure/persistence/sqlite.d.ts +5 -1
  54. package/dist/infrastructure/persistence/sqlite.js +10 -2
  55. package/dist/infrastructure/persistence/sqliteSerializer.js +1 -1
  56. package/dist/infrastructure/persistence/statements.d.ts +2 -1
  57. package/dist/infrastructure/persistence/statements.js +3 -2
  58. package/dist/infrastructure/server/handlers/core.js +4 -4
  59. package/dist/infrastructure/server/tcp.d.ts +1 -0
  60. package/dist/infrastructure/server/tcp.js +23 -12
  61. package/dist/infrastructure/server/types.d.ts +2 -0
  62. package/dist/shared/msgpack.d.ts +3 -0
  63. package/dist/shared/msgpack.js +70 -0
  64. package/package.json +1 -1
@@ -1,128 +1,145 @@
1
- /**
2
- * bunqueue doctor - Diagnostic command
3
- * Checks client/server version, connectivity, health, and queue state
4
- */
5
1
  import { VERSION } from '../../shared/version';
6
- const green = '\x1b[32m';
7
- const red = '\x1b[31m';
8
- const yellow = '\x1b[33m';
9
- const dim = '\x1b[2m';
10
- const bold = '\x1b[1m';
11
- const reset = '\x1b[0m';
12
- function pass(msg) {
13
- console.log(` ${green}✓${reset} ${msg}`);
2
+ const style = {
3
+ green: '\x1b[32m',
4
+ red: '\x1b[31m',
5
+ yellow: '\x1b[33m',
6
+ dim: '\x1b[2m',
7
+ bold: '\x1b[1m',
8
+ reset: '\x1b[0m',
9
+ };
10
+ export async function fetchDoctorHealth(host, httpPort) {
11
+ const endpoint = `${host}:${httpPort}`;
12
+ try {
13
+ const response = await fetch(`http://${endpoint}/health`, {
14
+ signal: AbortSignal.timeout(5000),
15
+ });
16
+ if (!response.ok) {
17
+ return { kind: 'http-error', endpoint, status: response.status };
18
+ }
19
+ return {
20
+ kind: 'ok',
21
+ endpoint,
22
+ health: (await response.json()),
23
+ };
24
+ }
25
+ catch (error) {
26
+ return {
27
+ kind: 'network-error',
28
+ endpoint,
29
+ message: error instanceof Error ? error.message : String(error),
30
+ };
31
+ }
14
32
  }
15
- function fail(msg) {
16
- console.log(` ${red}✗${reset} ${msg}`);
33
+ /** Evaluate diagnostics without performing I/O or reading clocks. */
34
+ export function evaluateDoctor(input) {
35
+ if (input.kind !== 'ok') {
36
+ const error = input.kind === 'http-error' ? `HTTP ${input.status} from ${input.endpoint}` : input.message;
37
+ return {
38
+ clientVersion: VERSION,
39
+ endpoint: input.endpoint,
40
+ reachable: false,
41
+ error,
42
+ issues: 1,
43
+ fatal: true,
44
+ exitCode: 1,
45
+ };
46
+ }
47
+ const health = input.health;
48
+ let issues = 0;
49
+ if (health.version && health.version !== VERSION)
50
+ issues++;
51
+ if (health.status !== 'healthy')
52
+ issues++;
53
+ if ((health.queues?.dlq ?? 0) > 0)
54
+ issues++;
55
+ if ((health.memory?.rss ?? 0) > 512)
56
+ issues++;
57
+ return {
58
+ clientVersion: VERSION,
59
+ endpoint: input.endpoint,
60
+ reachable: true,
61
+ health,
62
+ issues,
63
+ fatal: false,
64
+ exitCode: issues > 0 ? 1 : 0,
65
+ };
17
66
  }
18
- function warn(msg) {
19
- console.log(` ${yellow}!${reset} ${msg}`);
67
+ function mark(kind, message) {
68
+ const decoration = kind === 'pass' ? `${style.green}✓` : kind === 'fail' ? `${style.red}✗` : `${style.yellow}!`;
69
+ return ` ${decoration}${style.reset} ${message}`;
20
70
  }
21
- function info(msg) {
22
- console.log(` ${dim}${msg}${reset}`);
71
+ function formatUptime(uptime) {
72
+ const hours = Math.floor(uptime / 3600);
73
+ const minutes = Math.floor((uptime % 3600) / 60);
74
+ const seconds = uptime % 60;
75
+ const parts = [];
76
+ if (hours > 0)
77
+ parts.push(`${hours}h`);
78
+ if (minutes > 0)
79
+ parts.push(`${minutes}m`);
80
+ parts.push(`${seconds}s`);
81
+ return parts.join(' ');
23
82
  }
24
- export async function runDoctor(host, httpPort) {
25
- console.log(`\n${bold}bunqueue doctor${reset}\n`);
26
- let issues = 0;
27
- // 1. Client version
28
- console.log(`${bold}Client${reset}`);
29
- pass(`Version: ${VERSION}`);
30
- // 2. Server connectivity + version
31
- console.log(`\n${bold}Server${reset}`);
32
- const url = `http://${host}:${httpPort}/health`;
33
- let health = null;
34
- try {
35
- const resp = await fetch(url, { signal: AbortSignal.timeout(5000) });
36
- if (resp.ok) {
37
- health = (await resp.json());
38
- pass(`Reachable at ${host}:${httpPort}`);
39
- }
83
+ export function formatDoctorText(report) {
84
+ const lines = [
85
+ '',
86
+ `${style.bold}bunqueue doctor${style.reset}`,
87
+ '',
88
+ `${style.bold}Client${style.reset}`,
89
+ mark('pass', `Version: ${report.clientVersion}`),
90
+ '',
91
+ `${style.bold}Server${style.reset}`,
92
+ ];
93
+ if (!report.reachable) {
94
+ if (report.error?.startsWith('HTTP '))
95
+ lines.push(mark('fail', report.error));
40
96
  else {
41
- fail(`HTTP ${resp.status} from ${host}:${httpPort}`);
42
- issues++;
97
+ lines.push(mark('fail', `Not reachable at ${report.endpoint}`));
98
+ if (report.error)
99
+ lines.push(` ${style.dim}${report.error}${style.reset}`);
43
100
  }
101
+ lines.push('', `${style.red}${style.bold}Cannot continue without server connection.${style.reset}`, `${style.dim}Start the server or use --port to specify the TCP port.${style.reset}`, '');
102
+ return lines.join('\n');
44
103
  }
45
- catch (err) {
46
- fail(`Not reachable at ${host}:${httpPort}`);
47
- info(err instanceof Error ? err.message : String(err));
48
- issues++;
49
- }
50
- if (!health) {
51
- console.log(`\n${red}${bold}Cannot continue without server connection.${reset}`);
52
- console.log(`${dim}Start the server or use --port to specify the TCP port.${reset}\n`);
53
- process.exit(1);
54
- }
55
- // 3. Server version + mismatch check
104
+ const health = report.health ?? {};
105
+ lines.push(mark('pass', `Reachable at ${report.endpoint}`));
56
106
  if (health.version) {
57
- pass(`Version: ${health.version}`);
107
+ lines.push(mark('pass', `Version: ${health.version}`));
58
108
  if (health.version !== VERSION) {
59
- warn(`Version mismatch! Client=${VERSION}, Server=${health.version}`);
60
- info('Update both client and server to the same version');
61
- issues++;
109
+ lines.push(mark('warn', `Version mismatch! Client=${VERSION}, Server=${health.version}`));
110
+ lines.push(` ${style.dim}Update both client and server to the same version${style.reset}`);
62
111
  }
63
112
  }
64
- // 4. Server status
65
- if (health.status === 'healthy') {
66
- pass(`Status: healthy`);
67
- }
68
- else {
69
- fail(`Status: ${health.status ?? 'unknown'}`);
70
- issues++;
71
- }
72
- // 5. Uptime
113
+ lines.push(health.status === 'healthy'
114
+ ? mark('pass', 'Status: healthy')
115
+ : mark('fail', `Status: ${health.status ?? 'unknown'}`));
73
116
  if (health.uptime !== undefined) {
74
- const hrs = Math.floor(health.uptime / 3600);
75
- const mins = Math.floor((health.uptime % 3600) / 60);
76
- const secs = health.uptime % 60;
77
- const parts = [];
78
- if (hrs > 0)
79
- parts.push(`${hrs}h`);
80
- if (mins > 0)
81
- parts.push(`${mins}m`);
82
- parts.push(`${secs}s`);
83
- pass(`Uptime: ${parts.join(' ')}`);
117
+ lines.push(mark('pass', `Uptime: ${formatUptime(health.uptime)}`));
84
118
  }
85
- // 6. Connections
86
119
  if (health.connections) {
87
- const c = health.connections;
88
- pass(`Connections: TCP=${c.tcp ?? 0}, WS=${c.ws ?? 0}, SSE=${c.sse ?? 0}`);
120
+ const connections = health.connections;
121
+ lines.push(mark('pass', `Connections: TCP=${connections.tcp ?? 0}, WS=${connections.ws ?? 0}, SSE=${connections.sse ?? 0}`));
89
122
  }
90
- // 7. Queue state
91
- console.log(`\n${bold}Queues${reset}`);
92
- const q = health.queues;
93
- if (q) {
94
- pass(`Waiting: ${q.waiting ?? 0}`);
95
- pass(`Active: ${q.active ?? 0}`);
96
- pass(`Delayed: ${q.delayed ?? 0}`);
97
- pass(`Completed: ${q.completed ?? 0}`);
98
- if ((q.dlq ?? 0) > 0) {
99
- warn(`DLQ: ${q.dlq} (dead-letter jobs need attention)`);
100
- issues++;
101
- }
102
- else {
103
- pass(`DLQ: 0`);
104
- }
123
+ lines.push('', `${style.bold}Queues${style.reset}`);
124
+ if (health.queues) {
125
+ const queues = health.queues;
126
+ lines.push(mark('pass', `Waiting: ${queues.waiting ?? 0}`), mark('pass', `Active: ${queues.active ?? 0}`), mark('pass', `Delayed: ${queues.delayed ?? 0}`), mark('pass', `Completed: ${queues.completed ?? 0}`), (queues.dlq ?? 0) > 0
127
+ ? mark('warn', `DLQ: ${queues.dlq} (dead-letter jobs need attention)`)
128
+ : mark('pass', 'DLQ: 0'));
105
129
  }
106
- // 8. Memory
107
- console.log(`\n${bold}Memory${reset}`);
130
+ lines.push('', `${style.bold}Memory${style.reset}`);
108
131
  if (health.memory) {
109
- const m = health.memory;
110
- const heapUsed = typeof m.heapUsed === 'number' ? m.heapUsed : 0;
111
- const rss = typeof m.rss === 'number' ? m.rss : 0;
112
- pass(`Heap: ${heapUsed}MB`);
113
- pass(`RSS: ${rss}MB`);
114
- if (rss > 512) {
115
- warn(`High memory usage (${rss}MB RSS)`);
116
- issues++;
117
- }
118
- }
119
- // Summary
120
- console.log('');
121
- if (issues === 0) {
122
- console.log(`${green}${bold}All checks passed.${reset}\n`);
132
+ const heapUsed = health.memory.heapUsed ?? 0;
133
+ const rss = health.memory.rss ?? 0;
134
+ lines.push(mark('pass', `Heap: ${heapUsed}MB`), mark('pass', `RSS: ${rss}MB`));
135
+ if (rss > 512)
136
+ lines.push(mark('warn', `High memory usage (${rss}MB RSS)`));
123
137
  }
124
- else {
125
- console.log(`${yellow}${bold}${issues} issue${issues > 1 ? 's' : ''} found.${reset}\n`);
126
- }
127
- process.exit(issues > 0 ? 1 : 0);
138
+ lines.push('', report.issues === 0
139
+ ? `${style.green}${style.bold}All checks passed.${style.reset}`
140
+ : `${style.yellow}${style.bold}${report.issues} issue${report.issues > 1 ? 's' : ''} found.${style.reset}`, '');
141
+ return lines.join('\n');
142
+ }
143
+ export async function runDoctor(host, httpPort) {
144
+ return evaluateDoctor(await fetchDoctorHealth(host, httpPort));
128
145
  }
@@ -33,7 +33,11 @@ export function parseNumberArg(value, name) {
33
33
  if (!/^-?\d+$/.test(value)) {
34
34
  throw new CommandError(`Invalid number for ${name}: ${value}`);
35
35
  }
36
- return parseInt(value, 10);
36
+ const parsed = Number(value);
37
+ if (!Number.isSafeInteger(parsed)) {
38
+ throw new CommandError(`Invalid number for ${name}: ${value}`);
39
+ }
40
+ return parsed === 0 ? 0 : parsed;
37
41
  }
38
42
  /** Parse job ID argument (UUIDs, numeric IDs, or custom IDs) */
39
43
  export function parseBigIntArg(value, name) {
@@ -0,0 +1,16 @@
1
+ export interface GlobalOptions {
2
+ host: string;
3
+ port: number;
4
+ token?: string;
5
+ tls?: boolean | {
6
+ rejectUnauthorized?: boolean;
7
+ caFile?: string;
8
+ };
9
+ json: boolean;
10
+ help: boolean;
11
+ version: boolean;
12
+ }
13
+ export declare function parseGlobalOptions(allArgs?: string[]): {
14
+ options: GlobalOptions;
15
+ commandArgs: string[];
16
+ };
@@ -0,0 +1,192 @@
1
+ import { resolveToken } from '../client/resolveToken';
2
+ function resolveEnvPort(currentPort) {
3
+ const envPort = Bun.env.TCP_PORT ?? Bun.env.BUNQUEUE_TCP_PORT ?? Bun.env.BQ_TCP_PORT;
4
+ if (!envPort)
5
+ return currentPort;
6
+ const parsed = parseInt(envPort, 10);
7
+ if (Number.isNaN(parsed) || parsed < 1 || parsed > 65535) {
8
+ console.warn(`Warning: Invalid env port "${envPort}". Using ${currentPort}.`);
9
+ return currentPort;
10
+ }
11
+ return parsed;
12
+ }
13
+ function resolveEnvHost(currentHost) {
14
+ return Bun.env.HOST ?? Bun.env.BUNQUEUE_HOST ?? Bun.env.BQ_HOST ?? currentHost;
15
+ }
16
+ function applyTlsFlag(arg, allArgs, index, state, commandArgs) {
17
+ if (arg === '--tls') {
18
+ state.enabled = true;
19
+ return index;
20
+ }
21
+ if (arg === '--tls-no-verify') {
22
+ state.noVerify = true;
23
+ return index;
24
+ }
25
+ if (arg === '--tls-ca') {
26
+ const value = allArgs[index + 1];
27
+ if (value === undefined || value.startsWith('-')) {
28
+ console.warn('Warning: --tls-ca requires a file path. Option ignored.');
29
+ return index;
30
+ }
31
+ state.caFile = value;
32
+ return index + 1;
33
+ }
34
+ if (arg.startsWith('--tls-ca=')) {
35
+ const value = arg.slice(9);
36
+ if (value)
37
+ state.caFile = value;
38
+ else
39
+ console.warn('Warning: --tls-ca= requires a file path. Option ignored.');
40
+ return index;
41
+ }
42
+ commandArgs.push(arg);
43
+ return index;
44
+ }
45
+ function buildTlsOption(state) {
46
+ if (state.noVerify || state.caFile !== undefined) {
47
+ return {
48
+ ...(state.noVerify && { rejectUnauthorized: false }),
49
+ ...(state.caFile !== undefined && { caFile: state.caFile }),
50
+ };
51
+ }
52
+ return state.enabled ? true : undefined;
53
+ }
54
+ function commandOwnsShortT(commandArgs) {
55
+ return commandArgs[0] === 'pull' || (commandArgs[0] === 'job' && commandArgs[1] === 'wait');
56
+ }
57
+ function applyTokenFlag(arg, allArgs, index, state, commandArgs) {
58
+ if (arg === '-t' && commandOwnsShortT(commandArgs)) {
59
+ commandArgs.push(arg);
60
+ return index;
61
+ }
62
+ const value = allArgs[index + 1];
63
+ if (value === undefined || value.startsWith('-')) {
64
+ console.warn('Warning: --token requires a value. Token not set.');
65
+ return index;
66
+ }
67
+ state.token = value;
68
+ return index + 1;
69
+ }
70
+ function applyHostFlag(allArgs, index, state) {
71
+ const value = allArgs[index + 1];
72
+ if (value === undefined || value.startsWith('-')) {
73
+ console.warn('Warning: --host requires a value. Using localhost.');
74
+ return index;
75
+ }
76
+ state.host = value;
77
+ state.hostExplicit = true;
78
+ return index + 1;
79
+ }
80
+ function applyPortFlag(allArgs, index, state) {
81
+ const value = allArgs[index + 1];
82
+ if (value === undefined || value.startsWith('-')) {
83
+ console.warn('Warning: --port requires a value. Using default port 6789.');
84
+ return index;
85
+ }
86
+ const parsed = parseInt(value, 10);
87
+ if (Number.isNaN(parsed) || parsed < 1 || parsed > 65535) {
88
+ console.warn(`Warning: Invalid port "${value}". Using default port 6789.`);
89
+ state.port = 6789;
90
+ }
91
+ else {
92
+ state.port = parsed;
93
+ state.portExplicit = true;
94
+ }
95
+ return index + 1;
96
+ }
97
+ function warnAmbiguousAttachedShort(arg, commandArgs) {
98
+ if (!/^-[Hpthv][^-\s]/.test(arg))
99
+ return;
100
+ if (arg.startsWith('-t') && commandOwnsShortT(commandArgs))
101
+ return;
102
+ console.warn(`Warning: "${arg}" looks like a short flag with an attached value; ` +
103
+ `use the separated form ("${arg.slice(0, 2)} ${arg.slice(2)}") or the long form.`);
104
+ }
105
+ export function parseGlobalOptions(allArgs = process.argv.slice(2)) {
106
+ const hp = {
107
+ host: 'localhost',
108
+ port: 6789,
109
+ hostExplicit: false,
110
+ portExplicit: false,
111
+ };
112
+ const tokenState = {};
113
+ const tlsState = { enabled: false, noVerify: false };
114
+ const commandArgs = [];
115
+ let json = false;
116
+ let help = false;
117
+ let version = false;
118
+ for (let index = 0; index < allArgs.length; index++) {
119
+ const arg = allArgs[index];
120
+ if (arg === '--') {
121
+ commandArgs.push(...allArgs.slice(index + 1));
122
+ break;
123
+ }
124
+ if (arg === '--host' || arg === '-H') {
125
+ index = applyHostFlag(allArgs, index, hp);
126
+ }
127
+ else if (arg === '--port' || arg === '-p') {
128
+ index = applyPortFlag(allArgs, index, hp);
129
+ }
130
+ else if (arg === '--token' || arg === '-t') {
131
+ index = applyTokenFlag(arg, allArgs, index, tokenState, commandArgs);
132
+ }
133
+ else if (arg.startsWith('--tls')) {
134
+ index = applyTlsFlag(arg, allArgs, index, tlsState, commandArgs);
135
+ }
136
+ else if (arg === '--json') {
137
+ json = true;
138
+ }
139
+ else if (arg === '--help' || (arg === '-h' && commandArgs.length === 0)) {
140
+ help = true;
141
+ }
142
+ else if (arg === '--version' || (arg === '-v' && commandArgs.length === 0)) {
143
+ version = true;
144
+ }
145
+ else if (arg.startsWith('--host=')) {
146
+ hp.host = arg.slice(7);
147
+ hp.hostExplicit = true;
148
+ }
149
+ else if (arg.startsWith('--port=')) {
150
+ const raw = arg.slice(7);
151
+ const parsed = parseInt(raw, 10);
152
+ if (Number.isNaN(parsed) || parsed < 1 || parsed > 65535) {
153
+ console.warn(`Warning: Invalid port "${raw}". Using default port 6789.`);
154
+ hp.port = 6789;
155
+ }
156
+ else {
157
+ hp.port = parsed;
158
+ hp.portExplicit = true;
159
+ }
160
+ }
161
+ else if (arg.startsWith('--token=')) {
162
+ const value = arg.slice(8);
163
+ if (value)
164
+ tokenState.token = value;
165
+ else
166
+ console.warn('Warning: --token= requires a value. Token not set.');
167
+ }
168
+ else {
169
+ warnAmbiguousAttachedShort(arg, commandArgs);
170
+ commandArgs.push(arg);
171
+ }
172
+ }
173
+ const serverMode = commandArgs[0] === 'start' || commandArgs.length === 0 || commandArgs[0]?.startsWith('-');
174
+ if (serverMode) {
175
+ if (hp.hostExplicit)
176
+ commandArgs.push('--host', hp.host);
177
+ if (hp.portExplicit)
178
+ commandArgs.push('--tcp-port', String(hp.port));
179
+ }
180
+ return {
181
+ options: {
182
+ host: hp.hostExplicit ? hp.host : resolveEnvHost(hp.host),
183
+ port: hp.portExplicit ? hp.port : resolveEnvPort(hp.port),
184
+ token: resolveToken(tokenState.token),
185
+ tls: buildTlsOption(tlsState),
186
+ json,
187
+ help,
188
+ version,
189
+ },
190
+ commandArgs,
191
+ };
192
+ }
@@ -3,11 +3,20 @@
3
3
  */
4
4
  /** Print version information */
5
5
  export declare function printVersion(version: string): void;
6
+ export declare function renderVersion(version: string): string;
7
+ /** Render main help, optionally without terminal escapes for JSON output. */
8
+ export declare function renderHelp(color?: boolean): string;
6
9
  /** Print main help */
7
10
  export declare function printHelp(): void;
11
+ /** Render server help. */
12
+ export declare function renderServerHelp(): string;
8
13
  /** Print server help */
9
14
  export declare function printServerHelp(): void;
15
+ /** Render push command help. */
16
+ export declare function renderPushHelp(): string;
10
17
  /** Print push command help */
11
18
  export declare function printPushHelp(): void;
19
+ /** Render cron add help. */
20
+ export declare function renderCronAddHelp(): string;
12
21
  /** Print cron add help */
13
22
  export declare function printCronAddHelp(): void;
package/dist/cli/help.js CHANGED
@@ -3,15 +3,18 @@
3
3
  */
4
4
  /** Print version information */
5
5
  export function printVersion(version) {
6
- console.log(`bunqueue v${version}`);
6
+ console.log(renderVersion(version));
7
7
  }
8
- /** Print main help */
9
- export function printHelp() {
10
- const magenta = '\x1b[35m';
11
- const reset = '\x1b[0m';
12
- const dim = '\x1b[2m';
13
- const bold = '\x1b[1m';
14
- console.log(`
8
+ export function renderVersion(version) {
9
+ return `bunqueue v${version}`;
10
+ }
11
+ /** Render main help, optionally without terminal escapes for JSON output. */
12
+ export function renderHelp(color = true) {
13
+ const magenta = color ? '\x1b[35m' : '';
14
+ const reset = color ? '\x1b[0m' : '';
15
+ const dim = color ? '\x1b[2m' : '';
16
+ const bold = color ? '\x1b[1m' : '';
17
+ return `
15
18
  ${magenta} (\\(\\ ${reset}
16
19
  ${magenta} ( -.-) ${bold}bunqueue${reset} ${dim}- High-performance job queue for Bun${reset}
17
20
  ${magenta} o_(")(") ${reset}
@@ -85,11 +88,13 @@ MONITORING:
85
88
  stats Show server statistics
86
89
  metrics Show Prometheus metrics
87
90
  health Health check
91
+ ping Check TCP connectivity
88
92
  version Show client and server version
89
93
  doctor Run diagnostics (version, health, queues)
90
94
 
91
95
  BACKUP (S3):
92
96
  backup now Create backup immediately
97
+ backup create Alias for backup now
93
98
  backup list List available backups
94
99
  backup restore <key> [-f] Restore from backup
95
100
  backup status Show backup configuration
@@ -115,11 +120,15 @@ EXAMPLES:
115
120
  bunqueue job get 12345
116
121
  bunqueue queue list
117
122
  bunqueue stats --json
118
- `);
123
+ `;
119
124
  }
120
- /** Print server help */
121
- export function printServerHelp() {
122
- console.log(`
125
+ /** Print main help */
126
+ export function printHelp() {
127
+ console.log(renderHelp());
128
+ }
129
+ /** Render server help. */
130
+ export function renderServerHelp() {
131
+ return `
123
132
  Usage: bunqueue start [options]
124
133
 
125
134
  Start the bunQ server.
@@ -138,11 +147,15 @@ Examples:
138
147
  bunqueue start
139
148
  bunqueue start --tcp-port 7000 --http-port 7001
140
149
  bunqueue start --data-path ./data/queue.db
141
- `);
150
+ `;
142
151
  }
143
- /** Print push command help */
144
- export function printPushHelp() {
145
- console.log(`
152
+ /** Print server help */
153
+ export function printServerHelp() {
154
+ console.log(renderServerHelp());
155
+ }
156
+ /** Render push command help. */
157
+ export function renderPushHelp() {
158
+ return `
146
159
  Usage: bunqueue push <queue> <data> [options]
147
160
 
148
161
  Push a job to a queue.
@@ -171,11 +184,15 @@ Examples:
171
184
  bunqueue push emails '{"to":"user@test.com"}'
172
185
  bunqueue push tasks '{"action":"sync"}' --priority 10
173
186
  bunqueue push jobs '{"id":1}' --delay 60000 --max-attempts 5
174
- `);
187
+ `;
175
188
  }
176
- /** Print cron add help */
177
- export function printCronAddHelp() {
178
- console.log(`
189
+ /** Print push command help */
190
+ export function printPushHelp() {
191
+ console.log(renderPushHelp());
192
+ }
193
+ /** Render cron add help. */
194
+ export function renderCronAddHelp() {
195
+ return `
179
196
  Usage: bunqueue cron add <name> [options]
180
197
 
181
198
  Add a cron job.
@@ -194,5 +211,9 @@ Options:
194
211
  Examples:
195
212
  bunqueue cron add hourly-cleanup -q maintenance -d '{"task":"cleanup"}' -s "0 * * * *"
196
213
  bunqueue cron add health-check -q monitoring -d '{}' -e 60000
197
- `);
214
+ `;
215
+ }
216
+ /** Print cron add help */
217
+ export function printCronAddHelp() {
218
+ console.log(renderCronAddHelp());
198
219
  }
@@ -1,27 +1,3 @@
1
1
  #!/usr/bin/env bun
2
- /**
3
- * bunqueue CLI Entry Point
4
- * Routes to server or client mode based on arguments
5
- */
6
- /** Global CLI options */
7
- interface GlobalOptions {
8
- host: string;
9
- port: number;
10
- token?: string;
11
- /** TLS to the server: true = verify with system CAs, object = custom CA / no-verify */
12
- tls?: boolean | {
13
- rejectUnauthorized?: boolean;
14
- caFile?: string;
15
- };
16
- json: boolean;
17
- help: boolean;
18
- version: boolean;
19
- }
20
- /** Parse global options from process.argv */
21
- export declare function parseGlobalOptions(): {
22
- options: GlobalOptions;
23
- commandArgs: string[];
24
- };
25
- /** Main CLI entry */
2
+ export { parseGlobalOptions } from './globalOptions';
26
3
  export declare function main(): Promise<void>;
27
- export {};