ntfy-reverse-proxy 2.0.4 → 2.1.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 (192) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +10 -0
  3. package/build/src/cli/commands/config-io.d.ts +3 -3
  4. package/build/src/cli/commands/config-io.d.ts.map +1 -1
  5. package/build/src/cli/commands/config-io.js +1 -1
  6. package/build/src/cli/commands/config-io.js.map +1 -1
  7. package/build/src/cli/commands/context.d.ts +7 -7
  8. package/build/src/cli/commands/context.d.ts.map +1 -1
  9. package/build/src/cli/commands/context.js +1 -1
  10. package/build/src/cli/commands/context.js.map +1 -1
  11. package/build/src/cli/commands/deploy.d.ts +2 -2
  12. package/build/src/cli/commands/deploy.d.ts.map +1 -1
  13. package/build/src/cli/commands/deploy.js +72 -30
  14. package/build/src/cli/commands/deploy.js.map +1 -1
  15. package/build/src/cli/commands/generate.d.ts +2 -2
  16. package/build/src/cli/commands/generate.d.ts.map +1 -1
  17. package/build/src/cli/commands/generate.js +3 -3
  18. package/build/src/cli/commands/generate.js.map +1 -1
  19. package/build/src/cli/commands/server.d.ts +5 -5
  20. package/build/src/cli/commands/server.d.ts.map +1 -1
  21. package/build/src/cli/commands/server.js.map +1 -1
  22. package/build/src/cli/commands/settings.d.ts +3 -3
  23. package/build/src/cli/commands/settings.d.ts.map +1 -1
  24. package/build/src/cli/commands/settings.js.map +1 -1
  25. package/build/src/cli/commands/validate.d.ts +2 -2
  26. package/build/src/cli/commands/validate.d.ts.map +1 -1
  27. package/build/src/cli/commands/validate.js +3 -0
  28. package/build/src/cli/commands/validate.js.map +1 -1
  29. package/build/src/cli/index.d.ts +2 -2
  30. package/build/src/cli/index.d.ts.map +1 -1
  31. package/build/src/cli/index.js +4 -4
  32. package/build/src/cli/index.js.map +1 -1
  33. package/build/src/cli/menu/interactive.d.ts +2 -2
  34. package/build/src/cli/menu/interactive.d.ts.map +1 -1
  35. package/build/src/cli/menu/interactive.js +174 -84
  36. package/build/src/cli/menu/interactive.js.map +1 -1
  37. package/build/src/lib/regex.d.ts +4 -1
  38. package/build/src/lib/regex.d.ts.map +1 -1
  39. package/build/src/lib/regex.js +4 -1
  40. package/build/src/lib/regex.js.map +1 -1
  41. package/build/src/lib/schema.d.ts +24 -0
  42. package/build/src/lib/schema.d.ts.map +1 -1
  43. package/build/src/lib/schema.js +11 -2
  44. package/build/src/lib/schema.js.map +1 -1
  45. package/build/src/lib/utility.d.ts +2 -2
  46. package/build/src/lib/utility.d.ts.map +1 -1
  47. package/build/src/lib/utility.js +1 -1
  48. package/build/src/lib/utility.js.map +1 -1
  49. package/build/src/types/cli/commands/config-io.d.ts +12 -12
  50. package/build/src/types/cli/commands/context.d.ts +96 -58
  51. package/build/src/types/cli/commands/deploy.d.ts +342 -298
  52. package/build/src/types/cli/commands/generate.d.ts +40 -24
  53. package/build/src/types/cli/commands/server.d.ts +23 -23
  54. package/build/src/types/cli/commands/settings.d.ts +8 -8
  55. package/build/src/types/cli/commands/validate.d.ts +16 -16
  56. package/build/src/types/cli/index.d.ts +16 -20
  57. package/build/src/types/cli/menu/interactive.d.ts +233 -178
  58. package/build/src/types/lib/schema.d.ts +89 -81
  59. package/build/src/types/lib/utility.d.ts +4 -2
  60. package/build/src/types/shared.d.ts +85 -0
  61. package/build/src/types/tests/cli/commands/context.test.d.ts +102 -31
  62. package/build/src/types/tests/cli/commands/generate.test.d.ts +50 -4
  63. package/build/src/types/tests/cli/commands/server.test.d.ts +88 -23
  64. package/build/src/types/tests/cli/commands/settings.test.d.ts +65 -21
  65. package/build/src/types/tests/cli/commands/validate.test.d.ts +69 -8
  66. package/build/src/types/tests/cli/menu/interactive.test.d.ts +2 -2
  67. package/build/src/types/tests/lib/schema.test.d.ts +258 -3
  68. package/build/src/types/tests/worker/index.test.d.ts +166 -8
  69. package/build/src/types/tests/worker/interpreters/ntfy-json.test.d.ts +94 -10
  70. package/build/src/types/tests/worker/interpreters/pfsense.test.d.ts +163 -4
  71. package/build/src/types/tests/worker/interpreters/plain-text.test.d.ts +67 -4
  72. package/build/src/types/tests/worker/interpreters/seerr.test.d.ts +138 -3
  73. package/build/src/types/tests/worker/interpreters/statuspage.test.d.ts +235 -30
  74. package/build/src/types/tests/worker/interpreters/synology.test.d.ts +61 -3
  75. package/build/src/types/tests/worker/interpreters/unifi.test.d.ts +93 -3
  76. package/build/src/types/tests/worker/landing/page.test.d.ts +73 -50
  77. package/build/src/types/tests/worker/pipeline/accumulate.test.d.ts +226 -15
  78. package/build/src/types/tests/worker/pipeline/authenticate.test.d.ts +148 -4
  79. package/build/src/types/tests/worker/pipeline/email.test.d.ts +82 -8
  80. package/build/src/types/tests/worker/pipeline/format.test.d.ts +112 -32
  81. package/build/src/types/tests/worker/pipeline/interpret.test.d.ts +109 -17
  82. package/build/src/types/tests/worker/pipeline/parse.test.d.ts +70 -5
  83. package/build/src/types/tests/worker/pipeline/receive.test.d.ts +156 -15
  84. package/build/src/types/tests/worker/pipeline/respond.test.d.ts +129 -10
  85. package/build/src/types/tests/worker/pipeline/route.test.d.ts +412 -74
  86. package/build/src/types/tests/worker/pipeline/send.test.d.ts +58 -23
  87. package/build/src/types/tests/worker/pipeline/split.test.d.ts +47 -9
  88. package/build/src/types/worker/handlers.d.ts +193 -0
  89. package/build/src/types/worker/index.d.ts +58 -203
  90. package/build/src/types/worker/interpreters/ntfy-json.d.ts +10 -10
  91. package/build/src/types/worker/interpreters/pfsense.d.ts +57 -49
  92. package/build/src/types/worker/interpreters/plain-text.d.ts +7 -7
  93. package/build/src/types/worker/interpreters/seerr.d.ts +63 -61
  94. package/build/src/types/worker/interpreters/statuspage.d.ts +201 -116
  95. package/build/src/types/worker/interpreters/synology.d.ts +48 -46
  96. package/build/src/types/worker/interpreters/unifi.d.ts +79 -54
  97. package/build/src/types/worker/landing/page.d.ts +30 -23
  98. package/build/src/types/worker/pipeline/accumulate.d.ts +46 -32
  99. package/build/src/types/worker/pipeline/authenticate.d.ts +94 -34
  100. package/build/src/types/worker/pipeline/email.d.ts +114 -50
  101. package/build/src/types/worker/pipeline/format.d.ts +31 -23
  102. package/build/src/types/worker/pipeline/interpret.d.ts +34 -34
  103. package/build/src/types/worker/pipeline/parse.d.ts +25 -19
  104. package/build/src/types/worker/pipeline/receive.d.ts +36 -34
  105. package/build/src/types/worker/pipeline/respond.d.ts +119 -63
  106. package/build/src/types/worker/pipeline/route.d.ts +33 -16
  107. package/build/src/types/worker/pipeline/send.d.ts +116 -79
  108. package/build/src/types/worker/pipeline/split.d.ts +21 -16
  109. package/build/src/worker/handlers.d.ts +5 -4
  110. package/build/src/worker/handlers.d.ts.map +1 -1
  111. package/build/src/worker/handlers.js +238 -202
  112. package/build/src/worker/handlers.js.map +1 -1
  113. package/build/src/worker/index.d.ts +2 -2
  114. package/build/src/worker/index.d.ts.map +1 -1
  115. package/build/src/worker/index.js +37 -9
  116. package/build/src/worker/index.js.map +1 -1
  117. package/build/src/worker/interpreters/ntfy-json.d.ts +2 -2
  118. package/build/src/worker/interpreters/ntfy-json.d.ts.map +1 -1
  119. package/build/src/worker/interpreters/ntfy-json.js.map +1 -1
  120. package/build/src/worker/interpreters/pfsense.d.ts +2 -2
  121. package/build/src/worker/interpreters/pfsense.d.ts.map +1 -1
  122. package/build/src/worker/interpreters/pfsense.js +20 -27
  123. package/build/src/worker/interpreters/pfsense.js.map +1 -1
  124. package/build/src/worker/interpreters/plain-text.d.ts +2 -2
  125. package/build/src/worker/interpreters/plain-text.d.ts.map +1 -1
  126. package/build/src/worker/interpreters/plain-text.js.map +1 -1
  127. package/build/src/worker/interpreters/seerr.d.ts +2 -2
  128. package/build/src/worker/interpreters/seerr.d.ts.map +1 -1
  129. package/build/src/worker/interpreters/seerr.js +16 -12
  130. package/build/src/worker/interpreters/seerr.js.map +1 -1
  131. package/build/src/worker/interpreters/statuspage.d.ts +2 -2
  132. package/build/src/worker/interpreters/statuspage.d.ts.map +1 -1
  133. package/build/src/worker/interpreters/statuspage.js +98 -47
  134. package/build/src/worker/interpreters/statuspage.js.map +1 -1
  135. package/build/src/worker/interpreters/synology.d.ts +2 -2
  136. package/build/src/worker/interpreters/synology.d.ts.map +1 -1
  137. package/build/src/worker/interpreters/synology.js +9 -5
  138. package/build/src/worker/interpreters/synology.js.map +1 -1
  139. package/build/src/worker/interpreters/unifi.d.ts +2 -2
  140. package/build/src/worker/interpreters/unifi.d.ts.map +1 -1
  141. package/build/src/worker/interpreters/unifi.js +34 -20
  142. package/build/src/worker/interpreters/unifi.js.map +1 -1
  143. package/build/src/worker/landing/page.d.ts +2 -2
  144. package/build/src/worker/landing/page.d.ts.map +1 -1
  145. package/build/src/worker/landing/page.js +4 -3
  146. package/build/src/worker/landing/page.js.map +1 -1
  147. package/build/src/worker/pipeline/accumulate.d.ts +5 -6
  148. package/build/src/worker/pipeline/accumulate.d.ts.map +1 -1
  149. package/build/src/worker/pipeline/accumulate.js +4 -11
  150. package/build/src/worker/pipeline/accumulate.js.map +1 -1
  151. package/build/src/worker/pipeline/authenticate.d.ts +2 -2
  152. package/build/src/worker/pipeline/authenticate.d.ts.map +1 -1
  153. package/build/src/worker/pipeline/authenticate.js +25 -7
  154. package/build/src/worker/pipeline/authenticate.js.map +1 -1
  155. package/build/src/worker/pipeline/email.d.ts +2 -2
  156. package/build/src/worker/pipeline/email.d.ts.map +1 -1
  157. package/build/src/worker/pipeline/email.js +34 -11
  158. package/build/src/worker/pipeline/email.js.map +1 -1
  159. package/build/src/worker/pipeline/format.d.ts +2 -3
  160. package/build/src/worker/pipeline/format.d.ts.map +1 -1
  161. package/build/src/worker/pipeline/format.js +2 -1
  162. package/build/src/worker/pipeline/format.js.map +1 -1
  163. package/build/src/worker/pipeline/interpret.d.ts +4 -3
  164. package/build/src/worker/pipeline/interpret.d.ts.map +1 -1
  165. package/build/src/worker/pipeline/interpret.js +7 -7
  166. package/build/src/worker/pipeline/interpret.js.map +1 -1
  167. package/build/src/worker/pipeline/parse.d.ts +2 -2
  168. package/build/src/worker/pipeline/parse.d.ts.map +1 -1
  169. package/build/src/worker/pipeline/parse.js +14 -7
  170. package/build/src/worker/pipeline/parse.js.map +1 -1
  171. package/build/src/worker/pipeline/receive.d.ts +2 -2
  172. package/build/src/worker/pipeline/receive.d.ts.map +1 -1
  173. package/build/src/worker/pipeline/receive.js +6 -6
  174. package/build/src/worker/pipeline/receive.js.map +1 -1
  175. package/build/src/worker/pipeline/respond.d.ts +2 -2
  176. package/build/src/worker/pipeline/respond.d.ts.map +1 -1
  177. package/build/src/worker/pipeline/respond.js +1 -1
  178. package/build/src/worker/pipeline/respond.js.map +1 -1
  179. package/build/src/worker/pipeline/route.d.ts +2 -3
  180. package/build/src/worker/pipeline/route.d.ts.map +1 -1
  181. package/build/src/worker/pipeline/route.js.map +1 -1
  182. package/build/src/worker/pipeline/send.d.ts +2 -2
  183. package/build/src/worker/pipeline/send.d.ts.map +1 -1
  184. package/build/src/worker/pipeline/send.js +80 -41
  185. package/build/src/worker/pipeline/send.js.map +1 -1
  186. package/build/src/worker/pipeline/split.d.ts +2 -2
  187. package/build/src/worker/pipeline/split.d.ts.map +1 -1
  188. package/build/src/worker/pipeline/split.js +4 -2
  189. package/build/src/worker/pipeline/split.js.map +1 -1
  190. package/package.json +7 -6
  191. package/build/src/types/tests/type-declarations.test.d.ts +0 -173
  192. package/build/src/types/worker/pipeline/shared.d.ts +0 -85
@@ -1,6 +1,6 @@
1
- import { existsSync, readFileSync } from 'fs';
2
- import { dirname, join } from 'path';
3
- import { fileURLToPath } from 'url';
1
+ import { existsSync, readFileSync } from 'node:fs';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
4
4
  import { Bootstrap, CLIHeader, Logger } from '@cbnventures/nova/toolkit';
5
5
  import chalk from 'chalk';
6
6
  import prompts from 'prompts';
@@ -64,19 +64,24 @@ async function interactiveMenu(configDirs) {
64
64
  message: chalk.cyan('What would you like to do?'),
65
65
  choices: [
66
66
  {
67
- title: 'Manage Servers', value: 'servers',
67
+ title: 'Manage Servers',
68
+ value: 'servers',
68
69
  },
69
70
  {
70
- title: 'Manage Contexts', value: 'contexts',
71
+ title: 'Manage Contexts',
72
+ value: 'contexts',
71
73
  },
72
74
  {
73
- title: 'Settings', value: 'settings',
75
+ title: 'Settings',
76
+ value: 'settings',
74
77
  },
75
78
  {
76
- title: 'Deploy', value: 'deploy',
79
+ title: 'Deploy',
80
+ value: 'deploy',
77
81
  },
78
82
  {
79
- title: 'Exit', value: 'exit',
83
+ title: 'Exit',
84
+ value: 'exit',
80
85
  },
81
86
  ],
82
87
  });
@@ -115,16 +120,20 @@ async function serverMenu(configPath) {
115
120
  message: chalk.cyan('Manage Servers'),
116
121
  choices: [
117
122
  {
118
- title: 'Add', value: 'add',
123
+ title: 'Add',
124
+ value: 'add',
119
125
  },
120
126
  {
121
- title: 'Edit', value: 'edit',
127
+ title: 'Edit',
128
+ value: 'edit',
122
129
  },
123
130
  {
124
- title: 'Remove', value: 'remove',
131
+ title: 'Remove',
132
+ value: 'remove',
125
133
  },
126
134
  {
127
- title: 'Back', value: 'back',
135
+ title: 'Back',
136
+ value: 'back',
128
137
  },
129
138
  ],
130
139
  });
@@ -199,7 +208,8 @@ async function serverMenu(configPath) {
199
208
  name: 'name',
200
209
  message: 'Select server to edit:',
201
210
  choices: servers.map((server) => ({
202
- title: server['name'], value: server['name'],
211
+ title: server['name'],
212
+ value: server['name'],
203
213
  })),
204
214
  });
205
215
  const name = selectResponse['name'];
@@ -217,8 +227,8 @@ async function serverMenu(configPath) {
217
227
  return 'URL must start with https://';
218
228
  }
219
229
  try {
220
- const urlInstance = new URL(value);
221
- void urlInstance;
230
+ const editUrlInstance = new URL(value);
231
+ void editUrlInstance;
222
232
  return true;
223
233
  }
224
234
  catch {
@@ -240,6 +250,9 @@ async function serverMenu(configPath) {
240
250
  },
241
251
  },
242
252
  ]);
253
+ if (updates['server'] === undefined || updates['token'] === undefined) {
254
+ break;
255
+ }
243
256
  const editImport = await import('../commands/server.js');
244
257
  const updatesServerString = updates['server'];
245
258
  const serverUrlTrimmed = updatesServerString.trim();
@@ -262,45 +275,46 @@ async function serverMenu(configPath) {
262
275
  }
263
276
  }
264
277
  catch (error) {
265
- const errorMessage = (error instanceof Error) ? error['message'] : String(error);
266
- Logger.error(`Error: ${errorMessage}`);
278
+ const editErrorMessage = (error instanceof Error) ? error['message'] : String(error);
279
+ Logger.error(`Error: ${editErrorMessage}`);
267
280
  }
268
281
  }
269
282
  else if (action === 'remove') {
270
283
  try {
271
- const servers = listServers(configPath);
272
- servers.sort((a, b) => a['name'].localeCompare(b['name']));
273
- if (servers['length'] === 0) {
284
+ const removeServers = listServers(configPath);
285
+ removeServers.sort((a, b) => a['name'].localeCompare(b['name']));
286
+ if (removeServers['length'] === 0) {
274
287
  Logger.warn('No servers to remove.');
275
288
  }
276
289
  else {
277
- const selectResponse = await prompts({
290
+ const removeSelectResponse = await prompts({
278
291
  type: 'select',
279
292
  name: 'name',
280
293
  message: 'Select server to remove:',
281
- choices: servers.map((server) => ({
282
- title: server['name'], value: server['name'],
294
+ choices: removeServers.map((server) => ({
295
+ title: server['name'],
296
+ value: server['name'],
283
297
  })),
284
298
  });
285
- const name = selectResponse['name'];
286
- if (name !== undefined) {
299
+ const removeName = removeSelectResponse['name'];
300
+ if (removeName !== undefined) {
287
301
  const confirmResponse = await prompts({
288
302
  type: 'confirm',
289
303
  name: 'confirmed',
290
- message: chalk.yellow(`Remove "${name}"?`),
304
+ message: chalk.yellow(`Remove "${removeName}"?`),
291
305
  initial: false,
292
306
  });
293
307
  const confirmed = confirmResponse['confirmed'];
294
308
  if (confirmed === true) {
295
- removeServer(configPath, name);
296
- Logger.info(`Server "${name}" removed.`);
309
+ removeServer(configPath, removeName);
310
+ Logger.info(`Server "${removeName}" removed.`);
297
311
  }
298
312
  }
299
313
  }
300
314
  }
301
315
  catch (error) {
302
- const errorMessage = (error instanceof Error) ? error['message'] : String(error);
303
- Logger.error(`Error: ${errorMessage}`);
316
+ const removeErrorMessage = (error instanceof Error) ? error['message'] : String(error);
317
+ Logger.error(`Error: ${removeErrorMessage}`);
304
318
  }
305
319
  }
306
320
  }
@@ -315,16 +329,20 @@ async function contextMenu(configPath) {
315
329
  message: chalk.cyan('Manage Contexts'),
316
330
  choices: [
317
331
  {
318
- title: 'Add', value: 'add',
332
+ title: 'Add',
333
+ value: 'add',
319
334
  },
320
335
  {
321
- title: 'Edit', value: 'edit',
336
+ title: 'Edit',
337
+ value: 'edit',
322
338
  },
323
339
  {
324
- title: 'Remove', value: 'remove',
340
+ title: 'Remove',
341
+ value: 'remove',
325
342
  },
326
343
  {
327
- title: 'Back', value: 'back',
344
+ title: 'Back',
345
+ value: 'back',
328
346
  },
329
347
  ],
330
348
  });
@@ -361,16 +379,18 @@ async function contextMenu(configPath) {
361
379
  name: 'name',
362
380
  message: 'Select context to edit:',
363
381
  choices: contexts.map((context) => ({
364
- title: context['name'], value: context['name'],
382
+ title: context['name'],
383
+ value: context['name'],
365
384
  })),
366
385
  });
367
386
  const name = selectResponse['name'];
368
387
  if (name !== undefined) {
369
388
  const current = contexts.find((context) => context['name'] === name);
370
389
  if (current !== undefined) {
371
- const servers = listServers(configPath);
372
- const serverChoices = servers.map((server) => ({
373
- title: server['name'], value: server['name'],
390
+ const editServers = listServers(configPath);
391
+ const serverChoices = editServers.map((server) => ({
392
+ title: server['name'],
393
+ value: server['name'],
374
394
  }));
375
395
  const keepIdResponse = await prompts({
376
396
  type: 'confirm',
@@ -386,37 +406,46 @@ async function contextMenu(configPath) {
386
406
  }
387
407
  const httpChoices = [
388
408
  {
389
- title: 'Plain Text', value: 'plain-text',
409
+ title: 'Plain Text',
410
+ value: 'plain-text',
390
411
  },
391
412
  {
392
- title: 'ntfy JSON', value: 'ntfy-json',
413
+ title: 'ntfy JSON',
414
+ value: 'ntfy-json',
393
415
  },
394
416
  {
395
- title: 'Seerr', value: 'seerr',
417
+ title: 'Seerr',
418
+ value: 'seerr',
396
419
  },
397
420
  {
398
- title: 'Synology DSM', value: 'synology',
421
+ title: 'Synology DSM',
422
+ value: 'synology',
399
423
  },
400
424
  {
401
- title: 'Statuspage.io', value: 'statuspage',
425
+ title: 'Statuspage.io',
426
+ value: 'statuspage',
402
427
  },
403
428
  ];
404
429
  const emailChoices = [
405
430
  {
406
- title: 'Plain Text', value: 'plain-text',
431
+ title: 'Plain Text',
432
+ value: 'plain-text',
407
433
  },
408
434
  {
409
- title: 'pfSense', value: 'pfsense',
435
+ title: 'pfSense',
436
+ value: 'pfsense',
410
437
  },
411
438
  {
412
- title: 'UniFi', value: 'unifi',
439
+ title: 'UniFi',
440
+ value: 'unifi',
413
441
  },
414
442
  ];
415
443
  const knownChoices = (current['type'] === 'http') ? httpChoices : emailChoices;
416
444
  const exists = knownChoices.some((c) => c['value'] === current['interpreter']);
417
445
  if (exists === false) {
418
446
  knownChoices.unshift({
419
- title: `${current['interpreter']} (current, unknown)`, value: current['interpreter'],
447
+ title: `${current['interpreter']} (current, unknown)`,
448
+ value: current['interpreter'],
420
449
  });
421
450
  }
422
451
  const httpValues = [
@@ -458,6 +487,25 @@ async function contextMenu(configPath) {
458
487
  initial: currentErrorTopic,
459
488
  });
460
489
  const errorTopic = errorTopicResponse['error_topic'];
490
+ const currentErrorEvents = current['error_events'];
491
+ const errorEventsResponse = await prompts({
492
+ type: 'multiselect',
493
+ name: 'error_events',
494
+ message: 'Errors that notify the error topic (space to select):',
495
+ choices: [
496
+ {
497
+ title: 'Authentication (failed auth, scanner traffic)',
498
+ value: 'authentication',
499
+ selected: currentErrorEvents === undefined || currentErrorEvents.includes('authentication'),
500
+ },
501
+ {
502
+ title: 'Interpretation (interpreter errors)',
503
+ value: 'interpretation',
504
+ selected: currentErrorEvents === undefined || currentErrorEvents.includes('interpretation'),
505
+ },
506
+ ],
507
+ });
508
+ const errorEvents = errorEventsResponse['error_events'];
461
509
  const modeInitial = (current['mode'] === 'send-all') ? 1 : 0;
462
510
  const modeResponse = await prompts({
463
511
  type: 'select',
@@ -465,10 +513,12 @@ async function contextMenu(configPath) {
465
513
  message: 'Mode:',
466
514
  choices: [
467
515
  {
468
- title: 'Send to one server only', value: 'send-once',
516
+ title: 'Send to one server only',
517
+ value: 'send-once',
469
518
  },
470
519
  {
471
- title: 'Send to all servers', value: 'send-all',
520
+ title: 'Send to all servers',
521
+ value: 'send-all',
472
522
  },
473
523
  ],
474
524
  initial: modeInitial,
@@ -484,7 +534,8 @@ async function contextMenu(configPath) {
484
534
  const primaryServerIdx = serverChoices.findIndex((s) => s['value'] === current['primary_server']);
485
535
  if (primaryServerIdx < 0) {
486
536
  serverChoices.unshift({
487
- title: `${current['primary_server']} (current, not found)`, value: current['primary_server'],
537
+ title: `${current['primary_server']} (current, not found)`,
538
+ value: current['primary_server'],
488
539
  });
489
540
  }
490
541
  const primaryServerInitial = (primaryServerIdx >= 0) ? primaryServerIdx : 0;
@@ -532,6 +583,9 @@ async function contextMenu(configPath) {
532
583
  const errorTopicTrimmed = (errorTopicValue !== undefined) ? errorTopicValue.trim() : '';
533
584
  const resolvedErrorTopic = (errorTopicTrimmed !== '') ? errorTopicTrimmed : undefined;
534
585
  Reflect.set(updates, 'error_topic', resolvedErrorTopic);
586
+ if (errorEvents !== undefined) {
587
+ Reflect.set(updates, 'error_events', errorEvents);
588
+ }
535
589
  if (current['type'] === 'http' && current['token'] !== undefined) {
536
590
  const keepTokenResponse = await prompts({
537
591
  type: 'confirm',
@@ -555,9 +609,9 @@ async function contextMenu(configPath) {
555
609
  });
556
610
  const addToken = addTokenResponse['addToken'];
557
611
  if (addToken === true) {
558
- const newToken = generateToken();
559
- Reflect.set(updates, 'token', newToken);
560
- Logger.info(` New token: ${newToken}`);
612
+ const addNewToken = generateToken();
613
+ Reflect.set(updates, 'token', addNewToken);
614
+ Logger.info(` New token: ${addNewToken}`);
561
615
  }
562
616
  }
563
617
  else if (current['type'] === 'email') {
@@ -581,45 +635,46 @@ async function contextMenu(configPath) {
581
635
  }
582
636
  }
583
637
  catch (error) {
584
- const errorMessage = (error instanceof Error) ? error['message'] : String(error);
585
- Logger.error(`Error: ${errorMessage}`);
638
+ const editErrorMessage = (error instanceof Error) ? error['message'] : String(error);
639
+ Logger.error(`Error: ${editErrorMessage}`);
586
640
  }
587
641
  }
588
642
  else if (action === 'remove') {
589
643
  try {
590
- const contexts = listContexts(configPath);
591
- contexts.sort((a, b) => a['name'].localeCompare(b['name']));
592
- if (contexts['length'] === 0) {
644
+ const removeContexts = listContexts(configPath);
645
+ removeContexts.sort((a, b) => a['name'].localeCompare(b['name']));
646
+ if (removeContexts['length'] === 0) {
593
647
  Logger.warn('No contexts to remove.');
594
648
  }
595
649
  else {
596
- const selectResponse = await prompts({
650
+ const removeSelectResponse = await prompts({
597
651
  type: 'select',
598
652
  name: 'name',
599
653
  message: 'Select context to remove:',
600
- choices: contexts.map((context) => ({
601
- title: context['name'], value: context['name'],
654
+ choices: removeContexts.map((context) => ({
655
+ title: context['name'],
656
+ value: context['name'],
602
657
  })),
603
658
  });
604
- const name = selectResponse['name'];
605
- if (name !== undefined) {
659
+ const removeName = removeSelectResponse['name'];
660
+ if (removeName !== undefined) {
606
661
  const confirmResponse = await prompts({
607
662
  type: 'confirm',
608
663
  name: 'confirmed',
609
- message: chalk.yellow(`Remove "${name}"?`),
664
+ message: chalk.yellow(`Remove "${removeName}"?`),
610
665
  initial: false,
611
666
  });
612
667
  const confirmed = confirmResponse['confirmed'];
613
668
  if (confirmed === true) {
614
- removeContext(configPath, name);
615
- Logger.info(`Context "${name}" removed.`);
669
+ removeContext(configPath, removeName);
670
+ Logger.info(`Context "${removeName}" removed.`);
616
671
  }
617
672
  }
618
673
  }
619
674
  }
620
675
  catch (error) {
621
- const errorMessage = (error instanceof Error) ? error['message'] : String(error);
622
- Logger.error(`Error: ${errorMessage}`);
676
+ const removeErrorMessage = (error instanceof Error) ? error['message'] : String(error);
677
+ Logger.error(`Error: ${removeErrorMessage}`);
623
678
  }
624
679
  }
625
680
  }
@@ -633,10 +688,12 @@ async function addContextFlow(configPath, servers) {
633
688
  message: 'Context type:',
634
689
  choices: [
635
690
  {
636
- title: 'HTTP', value: 'http',
691
+ title: 'HTTP',
692
+ value: 'http',
637
693
  },
638
694
  {
639
- title: 'Email', value: 'email',
695
+ title: 'Email',
696
+ value: 'email',
640
697
  },
641
698
  ],
642
699
  });
@@ -646,30 +703,38 @@ async function addContextFlow(configPath, servers) {
646
703
  }
647
704
  const httpInterpreters = [
648
705
  {
649
- title: 'Plain Text', value: 'plain-text',
706
+ title: 'Plain Text',
707
+ value: 'plain-text',
650
708
  },
651
709
  {
652
- title: 'ntfy JSON', value: 'ntfy-json',
710
+ title: 'ntfy JSON',
711
+ value: 'ntfy-json',
653
712
  },
654
713
  {
655
- title: 'Seerr', value: 'seerr',
714
+ title: 'Seerr',
715
+ value: 'seerr',
656
716
  },
657
717
  {
658
- title: 'Synology DSM', value: 'synology',
718
+ title: 'Synology DSM',
719
+ value: 'synology',
659
720
  },
660
721
  {
661
- title: 'Statuspage.io', value: 'statuspage',
722
+ title: 'Statuspage.io',
723
+ value: 'statuspage',
662
724
  },
663
725
  ];
664
726
  const emailInterpreters = [
665
727
  {
666
- title: 'Plain Text', value: 'plain-text',
728
+ title: 'Plain Text',
729
+ value: 'plain-text',
667
730
  },
668
731
  {
669
- title: 'pfSense', value: 'pfsense',
732
+ title: 'pfSense',
733
+ value: 'pfsense',
670
734
  },
671
735
  {
672
- title: 'UniFi', value: 'unifi',
736
+ title: 'UniFi',
737
+ value: 'unifi',
673
738
  },
674
739
  ];
675
740
  const nameResponse = await prompts({
@@ -731,16 +796,36 @@ async function addContextFlow(configPath, servers) {
731
796
  message: 'ntfy error topic (blank to skip):',
732
797
  });
733
798
  const errorTopic = errorTopicResponse['error_topic'];
799
+ const errorEventsResponse = await prompts({
800
+ type: 'multiselect',
801
+ name: 'error_events',
802
+ message: 'Errors that notify the error topic (space to select):',
803
+ choices: [
804
+ {
805
+ title: 'Authentication (failed auth, scanner traffic)',
806
+ value: 'authentication',
807
+ selected: true,
808
+ },
809
+ {
810
+ title: 'Interpretation (interpreter errors)',
811
+ value: 'interpretation',
812
+ selected: true,
813
+ },
814
+ ],
815
+ });
816
+ const errorEvents = errorEventsResponse['error_events'];
734
817
  const modeResponse = await prompts({
735
818
  type: 'select',
736
819
  name: 'mode',
737
820
  message: 'Mode:',
738
821
  choices: [
739
822
  {
740
- title: 'Send to one server only', value: 'send-once',
823
+ title: 'Send to one server only',
824
+ value: 'send-once',
741
825
  },
742
826
  {
743
- title: 'Send to all servers', value: 'send-all',
827
+ title: 'Send to all servers',
828
+ value: 'send-all',
744
829
  },
745
830
  ],
746
831
  });
@@ -763,7 +848,8 @@ async function addContextFlow(configPath, servers) {
763
848
  name: 'primary_server',
764
849
  message: 'Primary server:',
765
850
  choices: servers.map((server) => ({
766
- title: server['name'], value: server['name'],
851
+ title: server['name'],
852
+ value: server['name'],
767
853
  })),
768
854
  });
769
855
  const primaryServer = primaryServerResponse['primary_server'];
@@ -775,7 +861,8 @@ async function addContextFlow(configPath, servers) {
775
861
  name: 'selectedServers',
776
862
  message: 'All servers for this context (space to select):',
777
863
  choices: servers.map((server) => ({
778
- title: server['name'], value: server['name'],
864
+ title: server['name'],
865
+ value: server['name'],
779
866
  })),
780
867
  });
781
868
  const selectedServers = selectedServersResponse['selectedServers'];
@@ -791,6 +878,7 @@ async function addContextFlow(configPath, servers) {
791
878
  const topicString = topic;
792
879
  const typedInterpreter = interpreter;
793
880
  const typedMode = mode;
881
+ const typedErrorEvents = errorEvents;
794
882
  if (contextType === 'http') {
795
883
  const autoToken = generateToken();
796
884
  const tokenResponse = await prompts({
@@ -809,6 +897,7 @@ async function addContextFlow(configPath, servers) {
809
897
  interpreter: typedInterpreter,
810
898
  topic: topicString,
811
899
  error_topic: resolvedErrorTopic,
900
+ error_events: typedErrorEvents,
812
901
  mode: typedMode,
813
902
  show_visitor_info: showVisitorInfo,
814
903
  primary_server: primaryServer,
@@ -832,6 +921,7 @@ async function addContextFlow(configPath, servers) {
832
921
  interpreter: typedInterpreter,
833
922
  topic: topicString,
834
923
  error_topic: resolvedErrorTopic,
924
+ error_events: typedErrorEvents,
835
925
  mode: typedMode,
836
926
  show_visitor_info: showVisitorInfo,
837
927
  primary_server: primaryServer,
@@ -893,8 +983,8 @@ async function settingsFlow(configPath) {
893
983
  Logger.info('Settings updated.');
894
984
  }
895
985
  catch (error) {
896
- const errorMessage = (error instanceof Error) ? error['message'] : String(error);
897
- Logger.error(`Error: ${errorMessage}`);
986
+ const updateErrorMessage = (error instanceof Error) ? error['message'] : String(error);
987
+ Logger.error(`Error: ${updateErrorMessage}`);
898
988
  }
899
989
  return;
900
990
  }