@hookbase/cli 1.0.1 → 1.0.2

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 (113) hide show
  1. package/dist/commands/api-keys.d.ts.map +1 -1
  2. package/dist/commands/api-keys.js +106 -50
  3. package/dist/commands/api-keys.js.map +1 -1
  4. package/dist/commands/applications.d.ts +27 -0
  5. package/dist/commands/applications.d.ts.map +1 -0
  6. package/dist/commands/applications.js +216 -0
  7. package/dist/commands/applications.js.map +1 -0
  8. package/dist/commands/cron-groups.d.ts +26 -0
  9. package/dist/commands/cron-groups.d.ts.map +1 -0
  10. package/dist/commands/cron-groups.js +282 -0
  11. package/dist/commands/cron-groups.js.map +1 -0
  12. package/dist/commands/cron.d.ts +60 -0
  13. package/dist/commands/cron.d.ts.map +1 -0
  14. package/dist/commands/cron.js +953 -0
  15. package/dist/commands/cron.js.map +1 -0
  16. package/dist/commands/deliveries.d.ts.map +1 -1
  17. package/dist/commands/deliveries.js +36 -29
  18. package/dist/commands/deliveries.js.map +1 -1
  19. package/dist/commands/destinations.d.ts.map +1 -1
  20. package/dist/commands/destinations.js +82 -52
  21. package/dist/commands/destinations.js.map +1 -1
  22. package/dist/commands/endpoints.d.ts +39 -0
  23. package/dist/commands/endpoints.d.ts.map +1 -0
  24. package/dist/commands/endpoints.js +349 -0
  25. package/dist/commands/endpoints.js.map +1 -0
  26. package/dist/commands/events.d.ts.map +1 -1
  27. package/dist/commands/events.js +15 -14
  28. package/dist/commands/events.js.map +1 -1
  29. package/dist/commands/groups/inbound.d.ts +8 -0
  30. package/dist/commands/groups/inbound.d.ts.map +1 -0
  31. package/dist/commands/groups/inbound.js +226 -0
  32. package/dist/commands/groups/inbound.js.map +1 -0
  33. package/dist/commands/groups/outbound.d.ts +8 -0
  34. package/dist/commands/groups/outbound.d.ts.map +1 -0
  35. package/dist/commands/groups/outbound.js +228 -0
  36. package/dist/commands/groups/outbound.js.map +1 -0
  37. package/dist/commands/groups/tools.d.ts +6 -0
  38. package/dist/commands/groups/tools.d.ts.map +1 -0
  39. package/dist/commands/groups/tools.js +243 -0
  40. package/dist/commands/groups/tools.js.map +1 -0
  41. package/dist/commands/logs.js +3 -3
  42. package/dist/commands/logs.js.map +1 -1
  43. package/dist/commands/outbound.d.ts +40 -0
  44. package/dist/commands/outbound.d.ts.map +1 -0
  45. package/dist/commands/outbound.js +389 -0
  46. package/dist/commands/outbound.js.map +1 -0
  47. package/dist/commands/routes.d.ts.map +1 -1
  48. package/dist/commands/routes.js +98 -72
  49. package/dist/commands/routes.js.map +1 -1
  50. package/dist/commands/send.d.ts +9 -0
  51. package/dist/commands/send.d.ts.map +1 -0
  52. package/dist/commands/send.js +132 -0
  53. package/dist/commands/send.js.map +1 -0
  54. package/dist/commands/sources.d.ts.map +1 -1
  55. package/dist/commands/sources.js +78 -42
  56. package/dist/commands/sources.js.map +1 -1
  57. package/dist/commands/tunnels.d.ts.map +1 -1
  58. package/dist/commands/tunnels.js +76 -40
  59. package/dist/commands/tunnels.js.map +1 -1
  60. package/dist/index.js +143 -309
  61. package/dist/index.js.map +1 -1
  62. package/dist/lib/api.d.ts +368 -5
  63. package/dist/lib/api.d.ts.map +1 -1
  64. package/dist/lib/api.js +308 -14
  65. package/dist/lib/api.js.map +1 -1
  66. package/dist/lib/config.d.ts +9 -0
  67. package/dist/lib/config.d.ts.map +1 -1
  68. package/dist/lib/config.js +22 -0
  69. package/dist/lib/config.js.map +1 -1
  70. package/dist/lib/logger.d.ts.map +1 -1
  71. package/dist/lib/logger.js +32 -15
  72. package/dist/lib/logger.js.map +1 -1
  73. package/dist/tui/App.d.ts.map +1 -1
  74. package/dist/tui/App.js +397 -47
  75. package/dist/tui/App.js.map +1 -1
  76. package/dist/tui/Dashboard.js +1 -1
  77. package/dist/tui/Dashboard.js.map +1 -1
  78. package/dist/tui/views/Analytics.d.ts.map +1 -1
  79. package/dist/tui/views/Analytics.js +11 -2
  80. package/dist/tui/views/Analytics.js.map +1 -1
  81. package/dist/tui/views/ApiKeys.d.ts +10 -0
  82. package/dist/tui/views/ApiKeys.d.ts.map +1 -0
  83. package/dist/tui/views/ApiKeys.js +211 -0
  84. package/dist/tui/views/ApiKeys.js.map +1 -0
  85. package/dist/tui/views/Cron.d.ts +10 -0
  86. package/dist/tui/views/Cron.d.ts.map +1 -0
  87. package/dist/tui/views/Cron.js +312 -0
  88. package/dist/tui/views/Cron.js.map +1 -0
  89. package/dist/tui/views/Destinations.d.ts.map +1 -1
  90. package/dist/tui/views/Destinations.js +38 -19
  91. package/dist/tui/views/Destinations.js.map +1 -1
  92. package/dist/tui/views/Events.d.ts.map +1 -1
  93. package/dist/tui/views/Events.js +22 -4
  94. package/dist/tui/views/Events.js.map +1 -1
  95. package/dist/tui/views/Outbound.d.ts +8 -0
  96. package/dist/tui/views/Outbound.d.ts.map +1 -0
  97. package/dist/tui/views/Outbound.js +543 -0
  98. package/dist/tui/views/Outbound.js.map +1 -0
  99. package/dist/tui/views/Overview.d.ts +4 -0
  100. package/dist/tui/views/Overview.d.ts.map +1 -1
  101. package/dist/tui/views/Overview.js +35 -11
  102. package/dist/tui/views/Overview.js.map +1 -1
  103. package/dist/tui/views/Routes.d.ts +12 -0
  104. package/dist/tui/views/Routes.d.ts.map +1 -0
  105. package/dist/tui/views/Routes.js +220 -0
  106. package/dist/tui/views/Routes.js.map +1 -0
  107. package/dist/tui/views/Sources.d.ts.map +1 -1
  108. package/dist/tui/views/Sources.js +22 -12
  109. package/dist/tui/views/Sources.js.map +1 -1
  110. package/dist/tui/views/Tunnels.d.ts.map +1 -1
  111. package/dist/tui/views/Tunnels.js +72 -13
  112. package/dist/tui/views/Tunnels.js.map +1 -1
  113. package/package.json +1 -1
@@ -0,0 +1,389 @@
1
+ import { confirm, checkbox } from '@inquirer/prompts';
2
+ import { ExitPromptError } from '@inquirer/core';
3
+ import * as api from '../lib/api.js';
4
+ import * as config from '../lib/config.js';
5
+ import * as logger from '../lib/logger.js';
6
+ /** Helper to check if an error is a prompt cancellation (Ctrl+C) */
7
+ function isPromptCancelled(error) {
8
+ return error instanceof ExitPromptError ||
9
+ (error instanceof Error && error.name === 'ExitPromptError');
10
+ }
11
+ function requireAuth() {
12
+ if (!config.isAuthenticated()) {
13
+ logger.error('Not logged in. Run "hookbase login" first.');
14
+ process.exit(1);
15
+ }
16
+ return true;
17
+ }
18
+ function formatStatus(status) {
19
+ switch (status) {
20
+ case 'delivered': return logger.green('delivered');
21
+ case 'pending': return logger.yellow('pending');
22
+ case 'processing': return logger.cyan('processing');
23
+ case 'failed': return logger.red('failed');
24
+ case 'exhausted': return logger.red('exhausted');
25
+ default: return logger.dimText(status);
26
+ }
27
+ }
28
+ // ============================================================================
29
+ // Messages Commands
30
+ // ============================================================================
31
+ export async function outboundListCommand(options) {
32
+ requireAuth();
33
+ const spinner = logger.spinner('Fetching messages...');
34
+ const result = await api.getWebhookMessages({
35
+ applicationId: options.app,
36
+ endpointId: options.endpoint,
37
+ status: options.status,
38
+ eventType: options.eventType,
39
+ limit: options.limit ? parseInt(options.limit, 10) : 50,
40
+ });
41
+ if (result.error) {
42
+ spinner.fail('Failed to fetch messages');
43
+ logger.error(result.error);
44
+ return;
45
+ }
46
+ spinner.stop();
47
+ const raw = result.data;
48
+ const messages = raw?.data || raw?.messages || [];
49
+ const pagination = raw?.pagination || {};
50
+ if (options.json) {
51
+ console.log(JSON.stringify({
52
+ messages,
53
+ total: pagination.total ?? raw?.total,
54
+ hasMore: pagination.hasMore ?? raw?.hasMore,
55
+ }, null, 2));
56
+ return;
57
+ }
58
+ if (messages.length === 0) {
59
+ logger.info('No outbound messages found');
60
+ logger.dim('Send webhook events with "hookbase outbound send"');
61
+ return;
62
+ }
63
+ logger.table(['ID', 'Event Type', 'Status', 'Attempts', 'Created'], messages.map((m) => [
64
+ m.id.substring(0, 12) + '...',
65
+ m.event_type || m.eventType,
66
+ formatStatus(m.status),
67
+ `${m.attempt_count ?? m.attemptCount ?? 0}/${m.max_attempts ?? m.maxAttempts ?? 5}`,
68
+ new Date(m.created_at || m.createdAt).toLocaleString(),
69
+ ]));
70
+ if (pagination.hasMore ?? raw?.hasMore) {
71
+ logger.log('');
72
+ logger.dim(`Showing ${messages.length} messages. Use --limit to see more.`);
73
+ }
74
+ }
75
+ export async function outboundGetCommand(messageId, options) {
76
+ requireAuth();
77
+ const spinner = logger.spinner('Fetching message...');
78
+ const result = await api.getWebhookMessage(messageId);
79
+ if (result.error) {
80
+ spinner.fail('Failed to fetch message');
81
+ logger.error(result.error);
82
+ return;
83
+ }
84
+ spinner.stop();
85
+ const message = result.data?.data || result.data?.message;
86
+ if (options.json) {
87
+ console.log(JSON.stringify(message, null, 2));
88
+ return;
89
+ }
90
+ if (!message) {
91
+ logger.error('Message not found');
92
+ return;
93
+ }
94
+ logger.log('');
95
+ logger.log(logger.bold('Message Details'));
96
+ logger.log('');
97
+ logger.log(`ID: ${message.id}`);
98
+ logger.log(`Event Type: ${message.event_type || message.eventType}`);
99
+ logger.log(`Status: ${formatStatus(message.status)}`);
100
+ logger.log(`Attempts: ${message.attempt_count ?? message.attemptCount ?? 0}/${message.max_attempts ?? message.maxAttempts ?? 5}`);
101
+ logger.log(`Application: ${message.application_id || message.applicationId}`);
102
+ logger.log(`Endpoint: ${message.endpoint_id || message.endpointId}`);
103
+ if (message.response_status || message.responseStatus) {
104
+ logger.log(`Response: ${message.response_status || message.responseStatus}`);
105
+ }
106
+ if (message.error_message || message.errorMessage) {
107
+ logger.log(`Error: ${logger.red(message.error_message || message.errorMessage)}`);
108
+ }
109
+ if (message.next_retry_at || message.nextRetryAt) {
110
+ logger.log(`Next Retry: ${new Date(message.next_retry_at || message.nextRetryAt).toLocaleString()}`);
111
+ }
112
+ if (message.delivered_at || message.deliveredAt) {
113
+ logger.log(`Delivered: ${new Date(message.delivered_at || message.deliveredAt).toLocaleString()}`);
114
+ }
115
+ logger.log(`Created: ${new Date(message.created_at || message.createdAt).toLocaleString()}`);
116
+ logger.log('');
117
+ if (message.payload) {
118
+ logger.log(logger.bold('Payload:'));
119
+ logger.log(JSON.stringify(message.payload, null, 2));
120
+ logger.log('');
121
+ }
122
+ }
123
+ export async function outboundRetryCommand(messageId, options) {
124
+ requireAuth();
125
+ try {
126
+ if (!options.yes) {
127
+ const confirmed = await confirm({
128
+ message: `Retry message ${messageId}?`,
129
+ default: true,
130
+ });
131
+ if (!confirmed) {
132
+ logger.info('Cancelled');
133
+ return;
134
+ }
135
+ }
136
+ }
137
+ catch (error) {
138
+ if (isPromptCancelled(error)) {
139
+ logger.log('');
140
+ logger.info('Cancelled');
141
+ return;
142
+ }
143
+ throw error;
144
+ }
145
+ const spinner = logger.spinner('Retrying message...');
146
+ const result = await api.retryWebhookMessage(messageId);
147
+ if (result.error) {
148
+ spinner.fail('Failed to retry message');
149
+ logger.error(result.error);
150
+ return;
151
+ }
152
+ spinner.succeed('Message queued for retry');
153
+ if (options.json) {
154
+ const retried = result.data?.data || result.data?.message;
155
+ console.log(JSON.stringify(retried, null, 2));
156
+ }
157
+ }
158
+ // ============================================================================
159
+ // DLQ Commands
160
+ // ============================================================================
161
+ export async function dlqListCommand(options) {
162
+ requireAuth();
163
+ const spinner = logger.spinner('Fetching DLQ messages...');
164
+ const result = await api.getDlqMessages({
165
+ applicationId: options.app,
166
+ endpointId: options.endpoint,
167
+ limit: options.limit ? parseInt(options.limit, 10) : 50,
168
+ });
169
+ if (result.error) {
170
+ spinner.fail('Failed to fetch DLQ messages');
171
+ logger.error(result.error);
172
+ return;
173
+ }
174
+ spinner.stop();
175
+ const dlqRaw = result.data;
176
+ const messages = dlqRaw?.data || dlqRaw?.messages || [];
177
+ const dlqPagination = dlqRaw?.pagination || {};
178
+ if (options.json) {
179
+ console.log(JSON.stringify({
180
+ messages,
181
+ total: dlqPagination.total ?? dlqRaw?.total,
182
+ hasMore: dlqPagination.hasMore ?? dlqRaw?.hasMore,
183
+ }, null, 2));
184
+ return;
185
+ }
186
+ if (messages.length === 0) {
187
+ logger.info('No messages in Dead Letter Queue');
188
+ logger.dim('This is good! All messages were delivered successfully.');
189
+ return;
190
+ }
191
+ logger.table(['ID', 'Event Type', 'Reason', 'Attempts', 'Created'], messages.map((m) => [
192
+ m.id.substring(0, 12) + '...',
193
+ m.event_type || m.eventType,
194
+ m.reason,
195
+ String(m.attempt_count ?? m.attemptCount ?? 0),
196
+ new Date(m.created_at || m.createdAt).toLocaleString(),
197
+ ]));
198
+ if (dlqPagination.hasMore ?? dlqRaw?.hasMore) {
199
+ logger.log('');
200
+ logger.dim(`Showing ${messages.length} messages. Use --limit to see more.`);
201
+ }
202
+ }
203
+ export async function dlqGetCommand(messageId, options) {
204
+ requireAuth();
205
+ const spinner = logger.spinner('Fetching DLQ message...');
206
+ const result = await api.getDlqMessage(messageId);
207
+ if (result.error) {
208
+ spinner.fail('Failed to fetch DLQ message');
209
+ logger.error(result.error);
210
+ return;
211
+ }
212
+ spinner.stop();
213
+ const message = result.data?.data || result.data?.message;
214
+ if (options.json) {
215
+ console.log(JSON.stringify(message, null, 2));
216
+ return;
217
+ }
218
+ if (!message) {
219
+ logger.error('DLQ message not found');
220
+ return;
221
+ }
222
+ logger.log('');
223
+ logger.log(logger.bold('DLQ Message Details'));
224
+ logger.log('');
225
+ logger.log(`ID: ${message.id}`);
226
+ logger.log(`Original Msg ID: ${message.original_message_id || message.originalMessageId}`);
227
+ logger.log(`Event Type: ${message.event_type || message.eventType}`);
228
+ logger.log(`Reason: ${logger.red(message.reason)}`);
229
+ logger.log(`Attempts: ${message.attempt_count ?? message.attemptCount ?? 0}`);
230
+ logger.log(`Application: ${message.application_id || message.applicationId}`);
231
+ logger.log(`Endpoint: ${message.endpoint_id || message.endpointId}`);
232
+ if (message.error_message || message.errorMessage) {
233
+ logger.log(`Error: ${message.error_message || message.errorMessage}`);
234
+ }
235
+ if (message.last_response_status || message.lastResponseStatus) {
236
+ logger.log(`Last Response: ${message.last_response_status || message.lastResponseStatus}`);
237
+ }
238
+ logger.log(`Created: ${new Date(message.created_at || message.createdAt).toLocaleString()}`);
239
+ logger.log('');
240
+ if (message.payload) {
241
+ logger.log(logger.bold('Payload:'));
242
+ logger.log(JSON.stringify(message.payload, null, 2));
243
+ logger.log('');
244
+ }
245
+ }
246
+ export async function dlqRetryCommand(messageId, options) {
247
+ requireAuth();
248
+ try {
249
+ if (!options.yes) {
250
+ const confirmed = await confirm({
251
+ message: `Retry DLQ message ${messageId}?`,
252
+ default: true,
253
+ });
254
+ if (!confirmed) {
255
+ logger.info('Cancelled');
256
+ return;
257
+ }
258
+ }
259
+ }
260
+ catch (error) {
261
+ if (isPromptCancelled(error)) {
262
+ logger.log('');
263
+ logger.info('Cancelled');
264
+ return;
265
+ }
266
+ throw error;
267
+ }
268
+ const spinner = logger.spinner('Retrying DLQ message...');
269
+ const result = await api.retryDlqMessage(messageId);
270
+ if (result.error) {
271
+ spinner.fail('Failed to retry DLQ message');
272
+ logger.error(result.error);
273
+ return;
274
+ }
275
+ spinner.succeed('DLQ message queued for retry');
276
+ if (options.json) {
277
+ const retried = result.data?.data || result.data?.message;
278
+ console.log(JSON.stringify(retried, null, 2));
279
+ }
280
+ }
281
+ export async function dlqBulkRetryCommand(options) {
282
+ requireAuth();
283
+ // First, fetch DLQ messages
284
+ const spinner = logger.spinner('Fetching DLQ messages...');
285
+ const result = await api.getDlqMessages({
286
+ applicationId: options.app,
287
+ endpointId: options.endpoint,
288
+ limit: options.limit ? parseInt(options.limit, 10) : 50,
289
+ });
290
+ if (result.error) {
291
+ spinner.fail('Failed to fetch DLQ messages');
292
+ logger.error(result.error);
293
+ return;
294
+ }
295
+ const bulkRaw = result.data;
296
+ const messages = bulkRaw?.data || bulkRaw?.messages || [];
297
+ spinner.stop();
298
+ if (messages.length === 0) {
299
+ logger.info('No messages in Dead Letter Queue to retry');
300
+ return;
301
+ }
302
+ let messageIds;
303
+ try {
304
+ if (options.yes) {
305
+ messageIds = messages.map((m) => m.id);
306
+ }
307
+ else {
308
+ // Let user select which messages to retry
309
+ messageIds = await checkbox({
310
+ message: `Select messages to retry (${messages.length} found):`,
311
+ choices: messages.map((m) => ({
312
+ name: `${m.id.substring(0, 12)}... - ${m.event_type || m.eventType} (${m.reason})`,
313
+ value: m.id,
314
+ checked: true,
315
+ })),
316
+ });
317
+ if (messageIds.length === 0) {
318
+ logger.info('No messages selected');
319
+ return;
320
+ }
321
+ const confirmed = await confirm({
322
+ message: `Retry ${messageIds.length} message(s)?`,
323
+ default: true,
324
+ });
325
+ if (!confirmed) {
326
+ logger.info('Cancelled');
327
+ return;
328
+ }
329
+ }
330
+ }
331
+ catch (error) {
332
+ if (isPromptCancelled(error)) {
333
+ logger.log('');
334
+ logger.info('Cancelled');
335
+ return;
336
+ }
337
+ throw error;
338
+ }
339
+ const retrySpinner = logger.spinner(`Retrying ${messageIds.length} messages...`);
340
+ const retryResult = await api.bulkRetryDlqMessages(messageIds);
341
+ if (retryResult.error) {
342
+ retrySpinner.fail('Failed to retry messages');
343
+ logger.error(retryResult.error);
344
+ return;
345
+ }
346
+ retrySpinner.succeed(`Retried ${retryResult.data?.retried || 0} messages`);
347
+ if (options.json) {
348
+ console.log(JSON.stringify(retryResult.data, null, 2));
349
+ return;
350
+ }
351
+ if (retryResult.data?.failed && retryResult.data.failed > 0) {
352
+ logger.warn(`${retryResult.data.failed} message(s) failed to retry`);
353
+ }
354
+ }
355
+ export async function dlqDeleteCommand(messageId, options) {
356
+ requireAuth();
357
+ try {
358
+ if (!options.yes) {
359
+ const confirmed = await confirm({
360
+ message: `Are you sure you want to delete DLQ message ${messageId}? This cannot be undone.`,
361
+ default: false,
362
+ });
363
+ if (!confirmed) {
364
+ logger.info('Cancelled');
365
+ return;
366
+ }
367
+ }
368
+ }
369
+ catch (error) {
370
+ if (isPromptCancelled(error)) {
371
+ logger.log('');
372
+ logger.info('Cancelled');
373
+ return;
374
+ }
375
+ throw error;
376
+ }
377
+ const spinner = logger.spinner('Deleting DLQ message...');
378
+ const result = await api.deleteDlqMessage(messageId);
379
+ if (result.error) {
380
+ spinner.fail('Failed to delete DLQ message');
381
+ logger.error(result.error);
382
+ return;
383
+ }
384
+ spinner.succeed('DLQ message deleted');
385
+ if (options.json) {
386
+ console.log(JSON.stringify({ success: true, messageId }, null, 2));
387
+ }
388
+ }
389
+ //# sourceMappingURL=outbound.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"outbound.js","sourceRoot":"","sources":["../../src/commands/outbound.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/commands/routes.ts"],"names":[],"mappings":"AAaA,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuClF;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4GhB;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAuCf;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GACA,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GACzC,OAAO,CAAC,IAAI,CAAC,CA4Bf"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/commands/routes.ts"],"names":[],"mappings":"AAoBA,wBAAsB,iBAAiB,CAAC,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAuClF;AAED,wBAAsB,mBAAmB,CAAC,OAAO,EAAE;IACjD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqHhB;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GAC1B,OAAO,CAAC,IAAI,CAAC,CAuCf;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB,GACA,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IAAE,GAAG,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,GACzC,OAAO,CAAC,IAAI,CAAC,CAqCf"}
@@ -1,7 +1,13 @@
1
1
  import { input, confirm, select } from '@inquirer/prompts';
2
+ import { ExitPromptError } from '@inquirer/core';
2
3
  import * as api from '../lib/api.js';
3
4
  import * as config from '../lib/config.js';
4
5
  import * as logger from '../lib/logger.js';
6
+ /** Helper to check if an error is a prompt cancellation (Ctrl+C) */
7
+ function isPromptCancelled(error) {
8
+ return error instanceof ExitPromptError ||
9
+ (error instanceof Error && error.name === 'ExitPromptError');
10
+ }
5
11
  function requireAuth() {
6
12
  if (!config.isAuthenticated()) {
7
13
  logger.error('Not logged in. Run "hookbase login" first.');
@@ -29,14 +35,14 @@ export async function routesListCommand(options) {
29
35
  logger.dim('Create one with "hookbase routes create"');
30
36
  return;
31
37
  }
32
- logger.table(['ID', 'Name', 'Source', 'Destination', 'Priority', 'Status', 'Deliveries'], routes.map(r => [
33
- r.id?.slice(0, 8) + '...' || '-',
38
+ logger.table(['ID', 'Name', 'Source', 'Destination', 'Priority', 'Status', 'Deliveries'], routes.map((r) => [
39
+ r.id || '-',
34
40
  r.name || '-',
35
- r.source_name || (r.source_id ? r.source_id.slice(0, 8) + '...' : '-'),
36
- r.destination_name || (r.destination_id ? r.destination_id.slice(0, 8) + '...' : '-'),
41
+ r.source_name || r.sourceName || r.source_id || r.sourceId || '-',
42
+ r.destination_name || r.destinationName || r.destination_id || r.destinationId || '-',
37
43
  String(r.priority ?? 0),
38
- r.is_active ? logger.green('active') : logger.dimText('inactive'),
39
- String(r.delivery_count || 0),
44
+ (r.is_active ?? r.isActive) ? logger.green('active') : logger.dimText('inactive'),
45
+ String(r.delivery_count ?? r.deliveryCount ?? 0),
40
46
  ]));
41
47
  }
42
48
  export async function routesCreateCommand(options) {
@@ -45,63 +51,73 @@ export async function routesCreateCommand(options) {
45
51
  let sourceId = options.source;
46
52
  let destinationId = options.destination;
47
53
  let priority = options.priority ? parseInt(options.priority, 10) : 0;
48
- // Interactive mode
49
- if (!name || !sourceId || !destinationId) {
50
- // Fetch sources and destinations for selection
51
- const [sourcesResult, destinationsResult] = await Promise.all([
52
- api.getSources(),
53
- api.getDestinations(),
54
- ]);
55
- const sources = sourcesResult.data?.sources || [];
56
- const destinations = destinationsResult.data?.destinations || [];
57
- if (sources.length === 0) {
58
- logger.error('No sources found. Create a source first with "hookbase sources create"');
59
- return;
60
- }
61
- if (destinations.length === 0) {
62
- logger.error('No destinations found. Create a destination first with "hookbase destinations create"');
63
- return;
54
+ // Interactive mode - wrapped in try-catch to handle Ctrl+C gracefully
55
+ try {
56
+ if (!name || !sourceId || !destinationId) {
57
+ // Fetch sources and destinations for selection
58
+ const [sourcesResult, destinationsResult] = await Promise.all([
59
+ api.getSources(),
60
+ api.getDestinations(),
61
+ ]);
62
+ const sources = sourcesResult.data?.sources || [];
63
+ const destinations = destinationsResult.data?.destinations || [];
64
+ if (sources.length === 0) {
65
+ logger.error('No sources found. Create a source first with "hookbase sources create"');
66
+ return;
67
+ }
68
+ if (destinations.length === 0) {
69
+ logger.error('No destinations found. Create a destination first with "hookbase destinations create"');
70
+ return;
71
+ }
72
+ name = name || await input({
73
+ message: 'Route name:',
74
+ validate: (value) => value.length > 0 || 'Name is required',
75
+ });
76
+ sourceId = sourceId || await select({
77
+ message: 'Select source:',
78
+ choices: sources.map(s => ({
79
+ name: `${s.name} (${s.slug})`,
80
+ value: s.id,
81
+ })),
82
+ });
83
+ destinationId = destinationId || await select({
84
+ message: 'Select destination:',
85
+ choices: destinations.map(d => ({
86
+ name: `${d.name} (${d.url})`,
87
+ value: d.id,
88
+ })),
89
+ });
90
+ const setPriority = await confirm({
91
+ message: 'Set a custom priority? (default is 0)',
92
+ default: false,
93
+ });
94
+ if (setPriority) {
95
+ const priorityInput = await input({
96
+ message: 'Priority (higher = runs first):',
97
+ default: '0',
98
+ validate: (value) => !isNaN(parseInt(value, 10)) || 'Must be a number',
99
+ });
100
+ priority = parseInt(priorityInput, 10);
101
+ }
64
102
  }
65
- name = name || await input({
66
- message: 'Route name:',
67
- validate: (value) => value.length > 0 || 'Name is required',
68
- });
69
- sourceId = sourceId || await select({
70
- message: 'Select source:',
71
- choices: sources.map(s => ({
72
- name: `${s.name} (${s.slug})`,
73
- value: s.id,
74
- })),
75
- });
76
- destinationId = destinationId || await select({
77
- message: 'Select destination:',
78
- choices: destinations.map(d => ({
79
- name: `${d.name} (${d.url})`,
80
- value: d.id,
81
- })),
82
- });
83
- const setPriority = await confirm({
84
- message: 'Set a custom priority? (default is 0)',
85
- default: false,
86
- });
87
- if (setPriority) {
88
- const priorityInput = await input({
89
- message: 'Priority (higher = runs first):',
90
- default: '0',
91
- validate: (value) => !isNaN(parseInt(value, 10)) || 'Must be a number',
103
+ if (!options.yes && !options.name) {
104
+ const confirmed = await confirm({
105
+ message: `Create route "${name}"?`,
106
+ default: true,
92
107
  });
93
- priority = parseInt(priorityInput, 10);
108
+ if (!confirmed) {
109
+ logger.info('Cancelled');
110
+ return;
111
+ }
94
112
  }
95
113
  }
96
- if (!options.yes && !options.name) {
97
- const confirmed = await confirm({
98
- message: `Create route "${name}"?`,
99
- default: true,
100
- });
101
- if (!confirmed) {
114
+ catch (error) {
115
+ if (isPromptCancelled(error)) {
116
+ logger.log('');
102
117
  logger.info('Cancelled');
103
118
  return;
104
119
  }
120
+ throw error;
105
121
  }
106
122
  const spinner = logger.spinner('Creating route...');
107
123
  const result = await api.createRoute({
@@ -126,8 +142,8 @@ export async function routesCreateCommand(options) {
126
142
  logger.box('Route Created', [
127
143
  `ID: ${route.id}`,
128
144
  `Name: ${route.name}`,
129
- `Source: ${route.source_name || route.source_id}`,
130
- `Destination: ${route.destination_name || route.destination_id}`,
145
+ `Source: ${route.source_name || route.sourceName || route.source_id || route.sourceId}`,
146
+ `Destination: ${route.destination_name || route.destinationName || route.destination_id || route.destinationId}`,
131
147
  `Priority: ${route.priority}`,
132
148
  ].join('\n'));
133
149
  }
@@ -156,15 +172,15 @@ export async function routesGetCommand(routeId, options) {
156
172
  logger.log('');
157
173
  logger.log(`ID: ${route.id}`);
158
174
  logger.log(`Name: ${route.name}`);
159
- logger.log(`Source: ${route.source_name || route.source_id}`);
160
- logger.log(`Destination: ${route.destination_name || route.destination_id}`);
175
+ logger.log(`Source: ${route.source_name || route.sourceName || route.source_id || route.sourceId}`);
176
+ logger.log(`Destination: ${route.destination_name || route.destinationName || route.destination_id || route.destinationId}`);
161
177
  logger.log(`Priority: ${route.priority}`);
162
- logger.log(`Status: ${route.is_active ? logger.green('active') : logger.red('inactive')}`);
163
- if (route.filter_id)
164
- logger.log(`Filter: ${route.filter_id}`);
165
- if (route.transform_id)
166
- logger.log(`Transform: ${route.transform_id}`);
167
- logger.log(`Deliveries: ${route.delivery_count || 0}`);
178
+ logger.log(`Status: ${(route.is_active ?? route.isActive) ? logger.green('active') : logger.red('inactive')}`);
179
+ if (route.filter_id || route.filterId)
180
+ logger.log(`Filter: ${route.filter_id || route.filterId}`);
181
+ if (route.transform_id || route.transformId)
182
+ logger.log(`Transform: ${route.transform_id || route.transformId}`);
183
+ logger.log(`Deliveries: ${route.delivery_count ?? route.deliveryCount ?? 0}`);
168
184
  logger.log('');
169
185
  }
170
186
  export async function routesUpdateCommand(routeId, options) {
@@ -200,15 +216,25 @@ export async function routesUpdateCommand(routeId, options) {
200
216
  }
201
217
  export async function routesDeleteCommand(routeId, options) {
202
218
  requireAuth();
203
- if (!options.yes) {
204
- const confirmed = await confirm({
205
- message: `Are you sure you want to delete route ${routeId}? This cannot be undone.`,
206
- default: false,
207
- });
208
- if (!confirmed) {
219
+ try {
220
+ if (!options.yes) {
221
+ const confirmed = await confirm({
222
+ message: `Are you sure you want to delete route ${routeId}? This cannot be undone.`,
223
+ default: false,
224
+ });
225
+ if (!confirmed) {
226
+ logger.info('Cancelled');
227
+ return;
228
+ }
229
+ }
230
+ }
231
+ catch (error) {
232
+ if (isPromptCancelled(error)) {
233
+ logger.log('');
209
234
  logger.info('Cancelled');
210
235
  return;
211
236
  }
237
+ throw error;
212
238
  }
213
239
  const spinner = logger.spinner('Deleting route...');
214
240
  const result = await api.deleteRoute(routeId);