@oneuptime/common 8.0.5579 → 8.0.5581

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 (181) hide show
  1. package/Models/DatabaseModels/AlertInternalNote.ts +58 -1
  2. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +1 -0
  3. package/Models/DatabaseModels/File.ts +1 -1
  4. package/Models/DatabaseModels/IncidentInternalNote.ts +58 -1
  5. package/Models/DatabaseModels/IncidentPublicNote.ts +58 -1
  6. package/Models/DatabaseModels/ScheduledMaintenanceInternalNote.ts +58 -1
  7. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +58 -1
  8. package/Models/DatabaseModels/StatusPageAnnouncement.ts +49 -0
  9. package/Server/API/AlertInternalNoteAPI.ts +96 -0
  10. package/Server/API/IncidentInternalNoteAPI.ts +96 -0
  11. package/Server/API/IncidentPublicNoteAPI.ts +96 -0
  12. package/Server/API/ScheduledMaintenanceInternalNoteAPI.ts +100 -0
  13. package/Server/API/ScheduledMaintenancePublicNoteAPI.ts +100 -0
  14. package/Server/API/StatusPageAPI.ts +585 -59
  15. package/Server/API/StatusPageAnnouncementAPI.ts +98 -0
  16. package/Server/API/UserAPI.ts +95 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.ts +79 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.ts +81 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.ts +79 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  21. package/Server/Middleware/ProjectAuthorization.ts +3 -1
  22. package/Server/Services/AlertInternalNoteService.ts +75 -2
  23. package/Server/Services/IncidentInternalNoteService.ts +76 -2
  24. package/Server/Services/IncidentPublicNoteService.ts +76 -2
  25. package/Server/Services/ScheduledMaintenanceInternalNoteService.ts +76 -2
  26. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +76 -2
  27. package/Server/Services/ScheduledMaintenanceService.ts +10 -7
  28. package/Server/Services/StatusPagePrivateUserService.ts +10 -7
  29. package/Server/Services/StatusPageService.ts +12 -7
  30. package/Server/Services/StatusPageSubscriberService.ts +19 -13
  31. package/Server/Utils/FileAttachmentMarkdownUtil.ts +98 -0
  32. package/Server/Utils/Monitor/Criteria/CompareCriteria.ts +9 -1
  33. package/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.ts +34 -0
  34. package/Server/Utils/Monitor/DataToProcess.ts +3 -1
  35. package/Server/Utils/Monitor/MonitorCriteriaDataExtractor.ts +13 -0
  36. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +13 -0
  37. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +20 -0
  38. package/Server/Utils/Monitor/MonitorResource.ts +18 -0
  39. package/Server/Utils/Response.ts +13 -0
  40. package/Server/Utils/Telemetry.ts +15 -0
  41. package/Types/File/MimeType.ts +18 -0
  42. package/Types/Monitor/CriteriaFilter.ts +3 -0
  43. package/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.ts +12 -0
  44. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  45. package/Types/Monitor/MonitorStep.ts +30 -0
  46. package/Types/Monitor/MonitorStepExceptionMonitor.ts +94 -0
  47. package/Types/Monitor/MonitorType.ts +10 -1
  48. package/Types/Telemetry/TelemetryQuery.ts +2 -1
  49. package/Types/Telemetry/TelemetryType.ts +1 -0
  50. package/UI/Components/AttachmentList/EventAttachmentList.tsx +121 -0
  51. package/UI/Components/EventItem/EventItem.tsx +22 -0
  52. package/UI/Components/Feed/FeedItem.tsx +9 -16
  53. package/UI/Components/FilePicker/FilePicker.tsx +441 -145
  54. package/UI/Components/Forms/Fields/FormField.tsx +32 -15
  55. package/UI/Components/Forms/FormSummary.tsx +168 -1
  56. package/UI/Components/Forms/ModelForm.tsx +46 -24
  57. package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
  58. package/UI/Components/Icon/Icon.tsx +1 -1
  59. package/UI/Utils/API/RequestOptions.ts +2 -0
  60. package/UI/Utils/ModelAPI/ModelAPI.ts +18 -0
  61. package/UI/Utils/User.ts +8 -0
  62. package/Utils/API.ts +11 -1
  63. package/build/dist/Models/DatabaseModels/AlertInternalNote.js +49 -1
  64. package/build/dist/Models/DatabaseModels/AlertInternalNote.js.map +1 -1
  65. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +1 -0
  66. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  67. package/build/dist/Models/DatabaseModels/File.js +1 -1
  68. package/build/dist/Models/DatabaseModels/File.js.map +1 -1
  69. package/build/dist/Models/DatabaseModels/IncidentInternalNote.js +49 -1
  70. package/build/dist/Models/DatabaseModels/IncidentInternalNote.js.map +1 -1
  71. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +49 -1
  72. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  73. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js +49 -1
  74. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceInternalNote.js.map +1 -1
  75. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +49 -1
  76. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  77. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +48 -0
  78. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  79. package/build/dist/Server/API/AlertInternalNoteAPI.js +68 -0
  80. package/build/dist/Server/API/AlertInternalNoteAPI.js.map +1 -0
  81. package/build/dist/Server/API/IncidentInternalNoteAPI.js +68 -0
  82. package/build/dist/Server/API/IncidentInternalNoteAPI.js.map +1 -0
  83. package/build/dist/Server/API/IncidentPublicNoteAPI.js +68 -0
  84. package/build/dist/Server/API/IncidentPublicNoteAPI.js.map +1 -0
  85. package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js +68 -0
  86. package/build/dist/Server/API/ScheduledMaintenanceInternalNoteAPI.js.map +1 -0
  87. package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js +68 -0
  88. package/build/dist/Server/API/ScheduledMaintenancePublicNoteAPI.js.map +1 -0
  89. package/build/dist/Server/API/StatusPageAPI.js +488 -85
  90. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  91. package/build/dist/Server/API/StatusPageAnnouncementAPI.js +68 -0
  92. package/build/dist/Server/API/StatusPageAnnouncementAPI.js.map +1 -0
  93. package/build/dist/Server/API/UserAPI.js +66 -0
  94. package/build/dist/Server/API/UserAPI.js.map +1 -0
  95. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js +34 -0
  96. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763471659817-MigrationName.js.map +1 -0
  97. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js +34 -0
  98. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763477560906-MigrationName.js.map +1 -0
  99. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js +34 -0
  100. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1763480947474-MigrationName.js.map +1 -0
  101. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  102. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  103. package/build/dist/Server/Middleware/ProjectAuthorization.js +4 -1
  104. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  105. package/build/dist/Server/Services/AlertInternalNoteService.js +54 -2
  106. package/build/dist/Server/Services/AlertInternalNoteService.js.map +1 -1
  107. package/build/dist/Server/Services/IncidentInternalNoteService.js +54 -2
  108. package/build/dist/Server/Services/IncidentInternalNoteService.js.map +1 -1
  109. package/build/dist/Server/Services/IncidentPublicNoteService.js +54 -2
  110. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  111. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js +54 -2
  112. package/build/dist/Server/Services/ScheduledMaintenanceInternalNoteService.js.map +1 -1
  113. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +54 -2
  114. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  115. package/build/dist/Server/Services/ScheduledMaintenanceService.js +6 -5
  116. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  117. package/build/dist/Server/Services/StatusPagePrivateUserService.js +6 -4
  118. package/build/dist/Server/Services/StatusPagePrivateUserService.js.map +1 -1
  119. package/build/dist/Server/Services/StatusPageService.js +7 -4
  120. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  121. package/build/dist/Server/Services/StatusPageSubscriberService.js +11 -7
  122. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  123. package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js +67 -0
  124. package/build/dist/Server/Utils/FileAttachmentMarkdownUtil.js.map +1 -0
  125. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js +6 -1
  126. package/build/dist/Server/Utils/Monitor/Criteria/CompareCriteria.js.map +1 -1
  127. package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js +34 -0
  128. package/build/dist/Server/Utils/Monitor/Criteria/ExceptionMonitorCriteria.js.map +1 -0
  129. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js +6 -0
  130. package/build/dist/Server/Utils/Monitor/MonitorCriteriaDataExtractor.js.map +1 -1
  131. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +10 -0
  132. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  133. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
  134. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  135. package/build/dist/Server/Utils/Monitor/MonitorResource.js +10 -0
  136. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  137. package/build/dist/Server/Utils/Response.js +8 -0
  138. package/build/dist/Server/Utils/Response.js.map +1 -1
  139. package/build/dist/Server/Utils/Telemetry.js +8 -1
  140. package/build/dist/Server/Utils/Telemetry.js.map +1 -1
  141. package/build/dist/Types/File/MimeType.js +18 -0
  142. package/build/dist/Types/File/MimeType.js.map +1 -1
  143. package/build/dist/Types/Monitor/CriteriaFilter.js +2 -0
  144. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  145. package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js +2 -0
  146. package/build/dist/Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse.js.map +1 -0
  147. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  148. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  149. package/build/dist/Types/Monitor/MonitorStep.js +20 -1
  150. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  151. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js +58 -0
  152. package/build/dist/Types/Monitor/MonitorStepExceptionMonitor.js.map +1 -0
  153. package/build/dist/Types/Monitor/MonitorType.js +9 -1
  154. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  155. package/build/dist/Types/Telemetry/TelemetryType.js +1 -0
  156. package/build/dist/Types/Telemetry/TelemetryType.js.map +1 -1
  157. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js +42 -0
  158. package/build/dist/UI/Components/AttachmentList/EventAttachmentList.js.map +1 -0
  159. package/build/dist/UI/Components/EventItem/EventItem.js +5 -1
  160. package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
  161. package/build/dist/UI/Components/Feed/FeedItem.js +6 -4
  162. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  163. package/build/dist/UI/Components/FilePicker/FilePicker.js +262 -77
  164. package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
  165. package/build/dist/UI/Components/Forms/Fields/FormField.js +24 -12
  166. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  167. package/build/dist/UI/Components/Forms/FormSummary.js +77 -1
  168. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
  169. package/build/dist/UI/Components/Forms/ModelForm.js +32 -18
  170. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  171. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
  172. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
  173. package/build/dist/UI/Components/Icon/Icon.js +1 -1
  174. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  175. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +30 -45
  176. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  177. package/build/dist/UI/Utils/User.js +7 -0
  178. package/build/dist/UI/Utils/User.js.map +1 -1
  179. package/build/dist/Utils/API.js +3 -0
  180. package/build/dist/Utils/API.js.map +1 -1
  181. package/package.json +6 -6
@@ -16,7 +16,7 @@ import ProjectCallSMSConfigService from "./ProjectCallSMSConfigService";
16
16
  import ProjectService, { CurrentPlan } from "./ProjectService";
17
17
  import SmsService from "./SmsService";
18
18
  import StatusPageService from "./StatusPageService";
19
- import { FileRoute } from "../../ServiceRoute";
19
+ import { StatusPageApiRoute } from "../../ServiceRoute";
20
20
  import Hostname from "../../Types/API/Hostname";
21
21
  import Protocol from "../../Types/API/Protocol";
22
22
  import URL from "../../Types/API/URL";
@@ -522,6 +522,8 @@ Stay informed about service availability! 🚀`;
522
522
 
523
523
  const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
524
524
  logger.debug(`HTTP Protocol: ${httpProtocol}`);
525
+ const statusPageIdString: string | null =
526
+ statusPage.id?.toString() || statusPage._id?.toString() || null;
525
527
 
526
528
  const confirmSubscriptionLink: string = this.getConfirmSubscriptionLink({
527
529
  statusPageUrl: statusPageURL,
@@ -547,12 +549,13 @@ Stay informed about service availability! 🚀`;
547
549
  templateType: EmailTemplateType.ConfirmStatusPageSubscription,
548
550
  vars: {
549
551
  statusPageName: statusPageName,
550
- logoUrl: statusPage.logoFileId
551
- ? new URL(httpProtocol, host)
552
- .addRoute(FileRoute)
553
- .addRoute("/image/" + statusPage.logoFileId)
554
- .toString()
555
- : "",
552
+ logoUrl:
553
+ statusPage.logoFileId && statusPageIdString
554
+ ? new URL(httpProtocol, host)
555
+ .addRoute(StatusPageApiRoute)
556
+ .addRoute(`/logo/${statusPageIdString}`)
557
+ .toString()
558
+ : "",
556
559
  statusPageUrl: statusPageURL,
557
560
  isPublicStatusPage: statusPage.isPublicStatusPage
558
561
  ? "true"
@@ -656,6 +659,8 @@ Stay informed about service availability! 🚀`;
656
659
 
657
660
  const httpProtocol: Protocol = await DatabaseConfig.getHttpProtocol();
658
661
  logger.debug(`HTTP Protocol: ${httpProtocol}`);
662
+ const statusPageIdString: string | null =
663
+ statusPage.id?.toString() || statusPage._id?.toString() || null;
659
664
 
660
665
  const unsubscribeLink: string = this.getUnsubscribeLink(
661
666
  URL.fromString(statusPageURL),
@@ -675,12 +680,13 @@ Stay informed about service availability! 🚀`;
675
680
  templateType: EmailTemplateType.SubscribedToStatusPage,
676
681
  vars: {
677
682
  statusPageName: statusPageName,
678
- logoUrl: statusPage.logoFileId
679
- ? new URL(httpProtocol, host)
680
- .addRoute(FileRoute)
681
- .addRoute("/image/" + statusPage.logoFileId)
682
- .toString()
683
- : "",
683
+ logoUrl:
684
+ statusPage.logoFileId && statusPageIdString
685
+ ? new URL(httpProtocol, host)
686
+ .addRoute(StatusPageApiRoute)
687
+ .addRoute(`/logo/${statusPageIdString}`)
688
+ .toString()
689
+ : "",
684
690
  statusPageUrl: statusPageURL,
685
691
  isPublicStatusPage: statusPage.isPublicStatusPage
686
692
  ? "true"
@@ -0,0 +1,98 @@
1
+ import File from "../../Models/DatabaseModels/File";
2
+ import { AppApiRoute } from "../../ServiceRoute";
3
+ import Route from "../../Types/API/Route";
4
+ import ObjectID from "../../Types/ObjectID";
5
+ import FileService from "../Services/FileService";
6
+ import QueryHelper from "../Types/Database/QueryHelper";
7
+ import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
8
+
9
+ export interface FileAttachmentMarkdownInput {
10
+ modelId: ObjectID;
11
+ attachmentIds: Array<ObjectID>;
12
+ attachmentApiPath: string;
13
+ }
14
+
15
+ export default class FileAttachmentMarkdownUtil {
16
+ public static async buildAttachmentMarkdown(
17
+ input: FileAttachmentMarkdownInput,
18
+ ): Promise<string> {
19
+ if (
20
+ !input.modelId ||
21
+ !input.attachmentIds ||
22
+ input.attachmentIds.length === 0
23
+ ) {
24
+ return "";
25
+ }
26
+
27
+ const uniqueIds: Array<string> = Array.from(
28
+ new Set(
29
+ input.attachmentIds
30
+ .map((id: ObjectID) => {
31
+ return id.toString();
32
+ })
33
+ .filter((value: string) => {
34
+ return Boolean(value);
35
+ }),
36
+ ),
37
+ );
38
+
39
+ if (uniqueIds.length === 0) {
40
+ return "";
41
+ }
42
+
43
+ const files: Array<File> = await FileService.findBy({
44
+ query: {
45
+ _id: QueryHelper.any(uniqueIds),
46
+ },
47
+ limit: LIMIT_PER_PROJECT,
48
+ skip: 0,
49
+ select: {
50
+ _id: true,
51
+ name: true,
52
+ },
53
+ props: {
54
+ isRoot: true,
55
+ },
56
+ });
57
+
58
+ if (!files.length) {
59
+ return "";
60
+ }
61
+
62
+ const fileById: Map<string, File> = new Map(
63
+ files
64
+ .filter((file: File) => {
65
+ return Boolean(file._id);
66
+ })
67
+ .map((file: File) => {
68
+ return [file._id!.toString(), file];
69
+ }),
70
+ );
71
+
72
+ const attachmentLines: Array<string> = [];
73
+
74
+ for (const id of input.attachmentIds) {
75
+ const key: string = id.toString();
76
+ const file: File | undefined = fileById.get(key);
77
+
78
+ if (!file) {
79
+ continue;
80
+ }
81
+
82
+ const fileName: string = file.name || "Attachment";
83
+
84
+ const route: Route = Route.fromString(AppApiRoute.toString())
85
+ .addRoute(input.attachmentApiPath)
86
+ .addRoute(`/${input.modelId.toString()}`)
87
+ .addRoute(`/${key}`);
88
+
89
+ attachmentLines.push(`- [${fileName}](${route.toString()})`);
90
+ }
91
+
92
+ if (!attachmentLines.length) {
93
+ return "";
94
+ }
95
+
96
+ return `\n\n**Attachments:**\n${attachmentLines.join("\n")}\n`;
97
+ }
98
+ }
@@ -636,7 +636,15 @@ export default class CompareCriteria {
636
636
  }
637
637
 
638
638
  if (typeof value === Typeof.Number) {
639
- return (value as number).toFixed(2);
639
+ const numericValue: number = value as number;
640
+
641
+ if (Number.isInteger(numericValue)) {
642
+ return numericValue.toString();
643
+ }
644
+
645
+ const roundedValue: number = Number(numericValue.toFixed(2));
646
+
647
+ return roundedValue.toString();
640
648
  }
641
649
 
642
650
  if (typeof value === Typeof.Boolean) {
@@ -0,0 +1,34 @@
1
+ import ExceptionMonitorResponse from "../../../../Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse";
2
+ import CaptureSpan from "../../Telemetry/CaptureSpan";
3
+ import DataToProcess from "../DataToProcess";
4
+ import CompareCriteria from "./CompareCriteria";
5
+ import {
6
+ CheckOn,
7
+ CriteriaFilter,
8
+ } from "../../../../Types/Monitor/CriteriaFilter";
9
+
10
+ export default class ExceptionMonitorCriteria {
11
+ @CaptureSpan()
12
+ public static async isMonitorInstanceCriteriaFilterMet(input: {
13
+ dataToProcess: DataToProcess;
14
+ criteriaFilter: CriteriaFilter;
15
+ }): Promise<string | null> {
16
+ let threshold: number | string | undefined | null =
17
+ input.criteriaFilter.value;
18
+
19
+ if (input.criteriaFilter.checkOn === CheckOn.ExceptionCount) {
20
+ threshold = CompareCriteria.convertToNumber(threshold);
21
+
22
+ const currentExceptionCount: number =
23
+ (input.dataToProcess as ExceptionMonitorResponse).exceptionCount || 0;
24
+
25
+ return CompareCriteria.compareCriteriaNumbers({
26
+ value: currentExceptionCount,
27
+ threshold: threshold as number,
28
+ criteriaFilter: input.criteriaFilter,
29
+ });
30
+ }
31
+
32
+ return null;
33
+ }
34
+ }
@@ -4,6 +4,7 @@ import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
4
4
  import LogMonitorResponse from "../../../Types/Monitor/LogMonitor/LogMonitorResponse";
5
5
  import TraceMonitorResponse from "../../../Types/Monitor/TraceMonitor/TraceMonitorResponse";
6
6
  import MetricMonitorResponse from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
7
+ import ExceptionMonitorResponse from "../../../Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse";
7
8
 
8
9
  type DataToProcess =
9
10
  | ProbeMonitorResponse
@@ -11,6 +12,7 @@ type DataToProcess =
11
12
  | ServerMonitorResponse
12
13
  | LogMonitorResponse
13
14
  | TraceMonitorResponse
14
- | MetricMonitorResponse;
15
+ | MetricMonitorResponse
16
+ | ExceptionMonitorResponse;
15
17
 
16
18
  export default DataToProcess;
@@ -14,6 +14,7 @@ import AggregatedResult from "../../../Types/BaseDatabase/AggregatedResult";
14
14
  import AggregateModel from "../../../Types/BaseDatabase/AggregatedModel";
15
15
  import MetricQueryConfigData from "../../../Types/Metrics/MetricQueryConfigData";
16
16
  import MetricFormulaConfigData from "../../../Types/Metrics/MetricFormulaConfigData";
17
+ import ExceptionMonitorResponse from "../../../Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse";
17
18
 
18
19
  export default class MonitorCriteriaDataExtractor {
19
20
  public static getProbeMonitorResponse(
@@ -79,6 +80,18 @@ export default class MonitorCriteriaDataExtractor {
79
80
  return null;
80
81
  }
81
82
 
83
+ public static getExceptionMonitorResponse(
84
+ dataToProcess: DataToProcess,
85
+ ): ExceptionMonitorResponse | null {
86
+ if (
87
+ (dataToProcess as ExceptionMonitorResponse).exceptionCount !== undefined
88
+ ) {
89
+ return dataToProcess as ExceptionMonitorResponse;
90
+ }
91
+
92
+ return null;
93
+ }
94
+
82
95
  public static getCustomCodeMonitorResponse(
83
96
  dataToProcess: DataToProcess,
84
97
  ): CustomCodeMonitorResponse | null {
@@ -9,6 +9,7 @@ import SyntheticMonitoringCriteria from "./Criteria/SyntheticMonitor";
9
9
  import LogMonitorCriteria from "./Criteria/LogMonitorCriteria";
10
10
  import MetricMonitorCriteria from "./Criteria/MetricMonitorCriteria";
11
11
  import TraceMonitorCriteria from "./Criteria/TraceMonitorCriteria";
12
+ import ExceptionMonitorCriteria from "./Criteria/ExceptionMonitorCriteria";
12
13
  import MonitorCriteriaMessageBuilder from "./MonitorCriteriaMessageBuilder";
13
14
  import DataToProcess from "./DataToProcess";
14
15
  import Monitor from "../../../Models/DatabaseModels/Monitor";
@@ -434,6 +435,18 @@ export default class MonitorCriteriaEvaluator {
434
435
  }
435
436
  }
436
437
 
438
+ if (input.monitor.monitorType === MonitorType.Exceptions) {
439
+ const exceptionMonitorResult: string | null =
440
+ await ExceptionMonitorCriteria.isMonitorInstanceCriteriaFilterMet({
441
+ dataToProcess: input.dataToProcess,
442
+ criteriaFilter: input.criteriaFilter,
443
+ });
444
+
445
+ if (exceptionMonitorResult) {
446
+ return exceptionMonitorResult;
447
+ }
448
+ }
449
+
437
450
  return null;
438
451
  }
439
452
  }
@@ -19,6 +19,7 @@ import SyntheticMonitorResponse from "../../../Types/Monitor/SyntheticMonitors/S
19
19
  import CustomCodeMonitorResponse from "../../../Types/Monitor/CustomCodeMonitor/CustomCodeMonitorResponse";
20
20
  import LogMonitorResponse from "../../../Types/Monitor/LogMonitor/LogMonitorResponse";
21
21
  import TraceMonitorResponse from "../../../Types/Monitor/TraceMonitor/TraceMonitorResponse";
22
+ import ExceptionMonitorResponse from "../../../Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse";
22
23
  import MonitorCriteriaMessageFormatter from "./MonitorCriteriaMessageFormatter";
23
24
  import MonitorCriteriaDataExtractor from "./MonitorCriteriaDataExtractor";
24
25
  import MonitorCriteriaExpectationBuilder from "./MonitorCriteriaExpectationBuilder";
@@ -161,6 +162,10 @@ export default class MonitorCriteriaObservationBuilder {
161
162
  return MonitorCriteriaObservationBuilder.describeMetricValueObservation(
162
163
  input,
163
164
  );
165
+ case CheckOn.ExceptionCount:
166
+ return MonitorCriteriaObservationBuilder.describeExceptionCountObservation(
167
+ input,
168
+ );
164
169
  default:
165
170
  return null;
166
171
  }
@@ -1083,6 +1088,21 @@ export default class MonitorCriteriaObservationBuilder {
1083
1088
  return `Span count was ${traceResponse.spanCount}.`;
1084
1089
  }
1085
1090
 
1091
+ private static describeExceptionCountObservation(input: {
1092
+ dataToProcess: DataToProcess;
1093
+ }): string | null {
1094
+ const exceptionResponse: ExceptionMonitorResponse | null =
1095
+ MonitorCriteriaDataExtractor.getExceptionMonitorResponse(
1096
+ input.dataToProcess,
1097
+ );
1098
+
1099
+ if (!exceptionResponse) {
1100
+ return null;
1101
+ }
1102
+
1103
+ return `Exception count was ${exceptionResponse.exceptionCount}.`;
1104
+ }
1105
+
1086
1106
  private static describeMetricValueObservation(input: {
1087
1107
  criteriaFilter: CriteriaFilter;
1088
1108
  dataToProcess: DataToProcess;
@@ -31,6 +31,7 @@ import LogMonitorResponse from "../../../Types/Monitor/LogMonitor/LogMonitorResp
31
31
  import MetricMonitorResponse from "../../../Types/Monitor/MetricMonitor/MetricMonitorResponse";
32
32
  import TelemetryType from "../../../Types/Telemetry/TelemetryType";
33
33
  import TraceMonitorResponse from "../../../Types/Monitor/TraceMonitor/TraceMonitorResponse";
34
+ import ExceptionMonitorResponse from "../../../Types/Monitor/ExceptionMonitor/ExceptionMonitorResponse";
34
35
  import { TelemetryQuery } from "../../../Types/Telemetry/TelemetryQuery";
35
36
  import MonitorIncident from "./MonitorIncident";
36
37
  import MonitorAlert from "./MonitorAlert";
@@ -557,6 +558,23 @@ export default class MonitorResourceUtil {
557
558
  );
558
559
  }
559
560
 
561
+ if (
562
+ dataToProcess &&
563
+ (dataToProcess as ExceptionMonitorResponse).exceptionQuery
564
+ ) {
565
+ const exceptionResponse: ExceptionMonitorResponse =
566
+ dataToProcess as ExceptionMonitorResponse;
567
+ telemetryQuery = {
568
+ telemetryQuery: exceptionResponse.exceptionQuery,
569
+ telemetryType: TelemetryType.Exception,
570
+ metricViewData: null,
571
+ };
572
+
573
+ logger.debug(
574
+ `${dataToProcess.monitorId.toString()} - Exception query found.`,
575
+ );
576
+ }
577
+
560
578
  const matchedCriteriaInstance: MonitorCriteriaInstance =
561
579
  criteriaInstanceMap[response.criteriaMetId!]!;
562
580
 
@@ -42,6 +42,7 @@ export default class Response {
42
42
  res: ExpressResponse,
43
43
  path: string,
44
44
  ): void {
45
+ Response.setNoCacheHeaders(res);
45
46
  res.sendFile(path);
46
47
  }
47
48
 
@@ -56,6 +57,7 @@ export default class Response {
56
57
  const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse;
57
58
 
58
59
  if (headers) {
60
+ Response.setNoCacheHeaders(oneUptimeResponse);
59
61
  for (const key in headers) {
60
62
  oneUptimeResponse.set(key, headers[key]?.toString() || "");
61
63
  }
@@ -322,4 +324,15 @@ export default class Response {
322
324
  oneUptimeResponse.writeHead(200, { "Content-Type": "text/javascript" });
323
325
  oneUptimeResponse.end(javascript);
324
326
  }
327
+
328
+ public static setNoCacheHeaders(res: ExpressResponse): void {
329
+ const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse;
330
+
331
+ oneUptimeResponse.setHeader(
332
+ "Cache-Control",
333
+ "no-store, no-cache, must-revalidate",
334
+ );
335
+ oneUptimeResponse.setHeader("Pragma", "no-cache");
336
+ oneUptimeResponse.setHeader("Expires", "0");
337
+ }
325
338
  }
@@ -27,6 +27,7 @@ import {
27
27
  } from "@opentelemetry/sdk-logs";
28
28
  import type { Resource as LogsResource } from "@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources/build/src/Resource";
29
29
  import {
30
+ Aggregation,
30
31
  MeterProvider,
31
32
  PeriodicExportingMetricReader,
32
33
  } from "@opentelemetry/sdk-metrics";
@@ -174,6 +175,20 @@ export default class Telemetry {
174
175
  compression: CompressionAlgorithm.GZIP,
175
176
  }) as unknown as PushMetricExporter;
176
177
 
178
+ // Force an SDK-side aggregation selector that matches the modern metrics API.
179
+ if (
180
+ typeof (metricExporter as { selectAggregation?: unknown })
181
+ .selectAggregation === "function"
182
+ ) {
183
+ (
184
+ metricExporter as unknown as {
185
+ selectAggregation: (..._args: Array<unknown>) => Aggregation;
186
+ }
187
+ ).selectAggregation = () => {
188
+ return Aggregation.Default();
189
+ };
190
+ }
191
+
177
192
  this.metricReader = new PeriodicExportingMetricReader({
178
193
  exporter: metricExporter,
179
194
  });
@@ -6,6 +6,24 @@ enum MimeType {
6
6
  jpg = "image/jpeg",
7
7
  jpeg = "image/jpeg",
8
8
  svg = "image/svg+xml",
9
+ gif = "image/gif",
10
+ webp = "image/webp",
11
+ pdf = "application/pdf",
12
+ doc = "application/msword",
13
+ docx = "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
14
+ txt = "text/plain",
15
+ md = "text/markdown",
16
+ csv = "text/csv",
17
+ rtf = "application/rtf",
18
+ odt = "application/vnd.oasis.opendocument.text",
19
+ json = "application/json",
20
+ zip = "application/zip",
21
+ xls = "application/vnd.ms-excel",
22
+ xlsx = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
23
+ ods = "application/vnd.oasis.opendocument.spreadsheet",
24
+ ppt = "application/vnd.ms-powerpoint",
25
+ pptx = "application/vnd.openxmlformats-officedocument.presentationml.presentation",
26
+ odp = "application/vnd.oasis.opendocument.presentation",
9
27
 
10
28
  // TODO add more mime types.
11
29
  }
@@ -42,6 +42,9 @@ export enum CheckOn {
42
42
  // Trace monitors.
43
43
  SpanCount = "Span Count",
44
44
 
45
+ // Exception monitors.
46
+ ExceptionCount = "Exception Count",
47
+
45
48
  // Metric Monitors.
46
49
  MetricValue = "Metric Value",
47
50
  }
@@ -0,0 +1,12 @@
1
+ import Query from "../../BaseDatabase/Query";
2
+ import ObjectID from "../../ObjectID";
3
+ import ExceptionInstance from "../../../Models/AnalyticsModels/ExceptionInstance";
4
+ import MonitorEvaluationSummary from "../MonitorEvaluationSummary";
5
+
6
+ export default interface ExceptionMonitorResponse {
7
+ projectId: ObjectID;
8
+ exceptionCount: number;
9
+ exceptionQuery: Query<ExceptionInstance>;
10
+ monitorId: ObjectID;
11
+ evaluationSummary?: MonitorEvaluationSummary | undefined;
12
+ }
@@ -121,6 +121,33 @@ export default class MonitorCriteriaInstance extends DatabaseProperty {
121
121
  return monitorCriteriaInstance;
122
122
  }
123
123
 
124
+ if (arg.monitorType === MonitorType.Exceptions) {
125
+ const monitorCriteriaInstance: MonitorCriteriaInstance =
126
+ new MonitorCriteriaInstance();
127
+
128
+ monitorCriteriaInstance.data = {
129
+ id: ObjectID.generate().toString(),
130
+ monitorStatusId: arg.monitorStatusId,
131
+ filterCondition: FilterCondition.Any,
132
+ filters: [
133
+ {
134
+ checkOn: CheckOn.ExceptionCount,
135
+ filterType: FilterType.EqualTo,
136
+ value: 0,
137
+ },
138
+ ],
139
+ incidents: [],
140
+ alerts: [],
141
+ changeMonitorStatus: true,
142
+ createIncidents: false,
143
+ createAlerts: false,
144
+ name: `Check if ${arg.monitorName} has no exceptions`,
145
+ description: `This criteria checks if the ${arg.monitorName} has no exceptions.`,
146
+ };
147
+
148
+ return monitorCriteriaInstance;
149
+ }
150
+
124
151
  if (arg.monitorType === MonitorType.Metrics) {
125
152
  const monitorCriteriaInstance: MonitorCriteriaInstance =
126
153
  new MonitorCriteriaInstance();
@@ -462,6 +489,46 @@ export default class MonitorCriteriaInstance extends DatabaseProperty {
462
489
  };
463
490
  }
464
491
 
492
+ if (arg.monitorType === MonitorType.Exceptions) {
493
+ monitorCriteriaInstance.data = {
494
+ id: ObjectID.generate().toString(),
495
+ monitorStatusId: arg.monitorStatusId,
496
+ filterCondition: FilterCondition.Any,
497
+ filters: [
498
+ {
499
+ checkOn: CheckOn.ExceptionCount,
500
+ filterType: FilterType.GreaterThan,
501
+ value: 0,
502
+ },
503
+ ],
504
+ incidents: [
505
+ {
506
+ title: `${arg.monitorName} has exceptions`,
507
+ description: `${arg.monitorName} has active exceptions.`,
508
+ incidentSeverityId: arg.incidentSeverityId,
509
+ autoResolveIncident: true,
510
+ id: ObjectID.generate().toString(),
511
+ onCallPolicyIds: [],
512
+ },
513
+ ],
514
+ alerts: [
515
+ {
516
+ title: `${arg.monitorName} has exceptions`,
517
+ description: `${arg.monitorName} has active exceptions.`,
518
+ alertSeverityId: arg.alertSeverityId,
519
+ autoResolveAlert: true,
520
+ id: ObjectID.generate().toString(),
521
+ onCallPolicyIds: [],
522
+ },
523
+ ],
524
+ createAlerts: false,
525
+ changeMonitorStatus: true,
526
+ createIncidents: true,
527
+ name: `Check if ${arg.monitorName} has exceptions`,
528
+ description: `This criteria checks if the ${arg.monitorName} has exceptions.`,
529
+ };
530
+ }
531
+
465
532
  if (arg.monitorType === MonitorType.Metrics) {
466
533
  monitorCriteriaInstance.data = {
467
534
  id: ObjectID.generate().toString(),
@@ -23,6 +23,9 @@ import MonitorStepTraceMonitor, {
23
23
  import MonitorStepMetricMonitor, {
24
24
  MonitorStepMetricMonitorUtil,
25
25
  } from "./MonitorStepMetricMonitor";
26
+ import MonitorStepExceptionMonitor, {
27
+ MonitorStepExceptionMonitorUtil,
28
+ } from "./MonitorStepExceptionMonitor";
26
29
  import Zod, { ZodSchema } from "../../Utils/Schema/Zod";
27
30
 
28
31
  export interface MonitorStepType {
@@ -57,6 +60,9 @@ export interface MonitorStepType {
57
60
 
58
61
  // Metric Monitor
59
62
  metricMonitor: MonitorStepMetricMonitor | undefined;
63
+
64
+ // Exception monitor
65
+ exceptionMonitor?: MonitorStepExceptionMonitor | undefined;
60
66
  }
61
67
 
62
68
  export default class MonitorStep extends DatabaseProperty {
@@ -80,6 +86,7 @@ export default class MonitorStep extends DatabaseProperty {
80
86
  logMonitor: undefined,
81
87
  traceMonitor: undefined,
82
88
  metricMonitor: undefined,
89
+ exceptionMonitor: undefined,
83
90
  };
84
91
  }
85
92
 
@@ -108,6 +115,7 @@ export default class MonitorStep extends DatabaseProperty {
108
115
  logMonitor: undefined,
109
116
  traceMonitor: undefined,
110
117
  metricMonitor: undefined,
118
+ exceptionMonitor: undefined,
111
119
  };
112
120
 
113
121
  return monitorStep;
@@ -186,6 +194,13 @@ export default class MonitorStep extends DatabaseProperty {
186
194
  return this;
187
195
  }
188
196
 
197
+ public setExceptionMonitor(
198
+ exceptionMonitor: MonitorStepExceptionMonitor,
199
+ ): MonitorStep {
200
+ this.data!.exceptionMonitor = exceptionMonitor;
201
+ return this;
202
+ }
203
+
189
204
  public setCustomCode(customCode: string): MonitorStep {
190
205
  this.data!.customCode = customCode;
191
206
  return this;
@@ -212,6 +227,7 @@ export default class MonitorStep extends DatabaseProperty {
212
227
  screenSizeTypes: undefined,
213
228
  browserTypes: undefined,
214
229
  lgoMonitor: undefined,
230
+ exceptionMonitor: undefined,
215
231
  },
216
232
  };
217
233
  }
@@ -310,6 +326,12 @@ export default class MonitorStep extends DatabaseProperty {
310
326
  MonitorStepTraceMonitorUtil.getDefault(),
311
327
  )
312
328
  : undefined,
329
+ exceptionMonitor: this.data.exceptionMonitor
330
+ ? MonitorStepExceptionMonitorUtil.toJSON(
331
+ this.data.exceptionMonitor ||
332
+ MonitorStepExceptionMonitorUtil.getDefault(),
333
+ )
334
+ : undefined,
313
335
  },
314
336
  });
315
337
  }
@@ -408,6 +430,9 @@ export default class MonitorStep extends DatabaseProperty {
408
430
  traceMonitor: json["traceMonitor"]
409
431
  ? (json["traceMonitor"] as JSONObject)
410
432
  : undefined,
433
+ exceptionMonitor: json["exceptionMonitor"]
434
+ ? (json["exceptionMonitor"] as JSONObject)
435
+ : undefined,
411
436
  }) as any;
412
437
 
413
438
  if (monitorStep.data && !monitorStep.data?.logMonitor) {
@@ -423,6 +448,11 @@ export default class MonitorStep extends DatabaseProperty {
423
448
  MonitorStepMetricMonitorUtil.getDefault();
424
449
  }
425
450
 
451
+ if (monitorStep.data && !monitorStep.data?.exceptionMonitor) {
452
+ monitorStep.data.exceptionMonitor =
453
+ MonitorStepExceptionMonitorUtil.getDefault();
454
+ }
455
+
426
456
  return monitorStep;
427
457
  }
428
458