@oneuptime/common 12.0.1 → 12.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 (205) hide show
  1. package/Models/DatabaseModels/Host.ts +12 -4
  2. package/Models/DatabaseModels/KubernetesContainer.ts +5 -4
  3. package/Models/DatabaseModels/KubernetesResource.ts +8 -7
  4. package/Models/DatabaseModels/PodmanResource.ts +6 -6
  5. package/Models/DatabaseModels/ServiceLevelObjective.ts +91 -0
  6. package/Models/DatabaseModels/StatusPage.ts +95 -0
  7. package/Server/API/TeamMemberAPI.ts +85 -0
  8. package/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.ts +84 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.ts +40 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.ts +131 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.ts +25 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  13. package/Server/Middleware/ProjectAuthorization.ts +66 -4
  14. package/Server/Services/BillingService.ts +600 -51
  15. package/Server/Services/CephClusterService.ts +47 -5
  16. package/Server/Services/CephResourceService.ts +43 -4
  17. package/Server/Services/CloudResourceService.ts +47 -5
  18. package/Server/Services/DatabaseService.ts +87 -6
  19. package/Server/Services/DockerHostService.ts +47 -5
  20. package/Server/Services/DockerResourceService.ts +62 -8
  21. package/Server/Services/DockerSwarmClusterService.ts +48 -5
  22. package/Server/Services/DockerSwarmResourceService.ts +53 -4
  23. package/Server/Services/HostService.ts +48 -5
  24. package/Server/Services/IoTDeviceService.ts +1 -17
  25. package/Server/Services/IoTFleetService.ts +47 -5
  26. package/Server/Services/KubernetesClusterService.ts +48 -5
  27. package/Server/Services/KubernetesContainerService.ts +50 -9
  28. package/Server/Services/KubernetesResourceService.ts +53 -7
  29. package/Server/Services/LabelService.ts +106 -1
  30. package/Server/Services/MonitorService.ts +57 -0
  31. package/Server/Services/PodmanHostService.ts +47 -5
  32. package/Server/Services/PodmanResourceService.ts +62 -8
  33. package/Server/Services/ProjectService.ts +165 -35
  34. package/Server/Services/ProxmoxClusterService.ts +47 -5
  35. package/Server/Services/ProxmoxResourceService.ts +43 -4
  36. package/Server/Services/RumApplicationService.ts +48 -5
  37. package/Server/Services/ServerlessFunctionService.ts +48 -5
  38. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +426 -0
  39. package/Server/Services/ServiceLevelObjectiveService.ts +39 -0
  40. package/Server/Services/StatusPageService.ts +95 -36
  41. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +18 -1
  42. package/Server/Services/StatusPageSubscriberService.ts +3 -0
  43. package/Server/Types/Database/JSONColumnQuery.ts +621 -0
  44. package/Server/Types/Database/Permissions/PublicPermission.ts +9 -2
  45. package/Server/Types/Database/QueryHelper.ts +17 -32
  46. package/Server/Utils/Database/TruncateColumnValue.ts +84 -0
  47. package/Tests/App/Dashboard/UsersTableGroupsByPerson.test.tsx +448 -0
  48. package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +704 -0
  49. package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +303 -0
  50. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +350 -0
  51. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyHeader.test.ts +362 -0
  52. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +687 -0
  53. package/Tests/Server/Services/BillingService.test.ts +78 -3
  54. package/Tests/Server/Services/BillingServiceChangePlanCancel.test.ts +645 -0
  55. package/Tests/Server/Services/BillingServiceTrialPlanChange.test.ts +1005 -0
  56. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +503 -0
  57. package/Tests/Server/Services/HostIpAddressesColumnWidth.test.ts +198 -0
  58. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +510 -0
  59. package/Tests/Server/Services/InventoryResourceNameColumnWidth.test.ts +500 -0
  60. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +586 -0
  61. package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +1242 -0
  62. package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +650 -0
  63. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +1 -0
  64. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +387 -0
  65. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +770 -0
  66. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +130 -0
  67. package/Tests/Server/Services/SloMonitorLabelRuleHooks.test.ts +352 -0
  68. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +29 -13
  69. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +69 -8
  70. package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +593 -0
  71. package/Tests/Server/Types/Database/Permissions/PublicPermission.test.ts +495 -0
  72. package/Tests/Server/Types/Database/QueryUtil.test.ts +113 -0
  73. package/Tests/Server/Utils/Database/TruncateColumnValue.test.ts +179 -0
  74. package/Tests/Types/Events/Recurring.test.ts +157 -0
  75. package/Tests/UI/Components/ModelTable/ModelTableGroupsProjectUsers.test.tsx +375 -0
  76. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +196 -0
  77. package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +739 -0
  78. package/Tests/UI/Utils/TeamMembersByUser.test.ts +633 -0
  79. package/Tests/Utils/StatusPage/ReportPeriod.test.ts +218 -0
  80. package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +291 -0
  81. package/Types/CustomField/CustomFieldDefinition.ts +24 -0
  82. package/Types/Date.ts +112 -0
  83. package/Types/Events/Recurring.ts +99 -1
  84. package/Types/StatusPage/StatusPageReport.ts +11 -0
  85. package/Types/StatusPage/StatusPageReportPeriodType.ts +21 -0
  86. package/UI/Components/ModelTable/CustomFieldColumns.tsx +2 -6
  87. package/UI/Components/ModelTable/useCustomFieldColumns.ts +21 -2
  88. package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +305 -0
  89. package/UI/Utils/TeamMembersByUser.ts +302 -0
  90. package/Utils/StatusPage/ReportPeriod.ts +236 -0
  91. package/Utils/Telemetry/HostIpAddresses.ts +98 -0
  92. package/build/dist/Models/DatabaseModels/Host.js +12 -4
  93. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  94. package/build/dist/Models/DatabaseModels/KubernetesContainer.js +4 -4
  95. package/build/dist/Models/DatabaseModels/KubernetesContainer.js.map +1 -1
  96. package/build/dist/Models/DatabaseModels/KubernetesResource.js +7 -7
  97. package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
  98. package/build/dist/Models/DatabaseModels/PodmanResource.js +6 -6
  99. package/build/dist/Models/DatabaseModels/PodmanResource.js.map +1 -1
  100. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +87 -0
  101. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  102. package/build/dist/Models/DatabaseModels/StatusPage.js +98 -0
  103. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  104. package/build/dist/Server/API/TeamMemberAPI.js +57 -2
  105. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  106. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js +45 -0
  107. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js.map +1 -0
  108. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js +31 -0
  109. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js.map +1 -0
  110. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js +90 -0
  111. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js.map +1 -0
  112. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js +14 -0
  113. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js.map +1 -0
  114. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  115. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  116. package/build/dist/Server/Middleware/ProjectAuthorization.js +59 -4
  117. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  118. package/build/dist/Server/Services/BillingService.js +466 -36
  119. package/build/dist/Server/Services/BillingService.js.map +1 -1
  120. package/build/dist/Server/Services/CephClusterService.js +42 -5
  121. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  122. package/build/dist/Server/Services/CephResourceService.js +28 -3
  123. package/build/dist/Server/Services/CephResourceService.js.map +1 -1
  124. package/build/dist/Server/Services/CloudResourceService.js +42 -5
  125. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  126. package/build/dist/Server/Services/DatabaseService.js +69 -2
  127. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  128. package/build/dist/Server/Services/DockerHostService.js +42 -5
  129. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  130. package/build/dist/Server/Services/DockerResourceService.js +34 -4
  131. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  132. package/build/dist/Server/Services/DockerSwarmClusterService.js +43 -5
  133. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  134. package/build/dist/Server/Services/DockerSwarmResourceService.js +28 -3
  135. package/build/dist/Server/Services/DockerSwarmResourceService.js.map +1 -1
  136. package/build/dist/Server/Services/HostService.js +43 -5
  137. package/build/dist/Server/Services/HostService.js.map +1 -1
  138. package/build/dist/Server/Services/IoTDeviceService.js +1 -8
  139. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  140. package/build/dist/Server/Services/IoTFleetService.js +42 -5
  141. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  142. package/build/dist/Server/Services/KubernetesClusterService.js +43 -5
  143. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  144. package/build/dist/Server/Services/KubernetesContainerService.js +29 -3
  145. package/build/dist/Server/Services/KubernetesContainerService.js.map +1 -1
  146. package/build/dist/Server/Services/KubernetesResourceService.js +32 -4
  147. package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
  148. package/build/dist/Server/Services/LabelService.js +92 -0
  149. package/build/dist/Server/Services/LabelService.js.map +1 -1
  150. package/build/dist/Server/Services/MonitorService.js +47 -0
  151. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  152. package/build/dist/Server/Services/PodmanHostService.js +42 -5
  153. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  154. package/build/dist/Server/Services/PodmanResourceService.js +34 -4
  155. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  156. package/build/dist/Server/Services/ProjectService.js +135 -21
  157. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  158. package/build/dist/Server/Services/ProxmoxClusterService.js +42 -5
  159. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  160. package/build/dist/Server/Services/ProxmoxResourceService.js +28 -3
  161. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  162. package/build/dist/Server/Services/RumApplicationService.js +43 -5
  163. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  164. package/build/dist/Server/Services/ServerlessFunctionService.js +43 -5
  165. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  166. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +347 -0
  167. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -0
  168. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +33 -1
  169. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  170. package/build/dist/Server/Services/StatusPageService.js +69 -46
  171. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  172. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +17 -1
  173. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  174. package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
  175. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  176. package/build/dist/Server/Types/Database/JSONColumnQuery.js +402 -0
  177. package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -0
  178. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js +9 -2
  179. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js.map +1 -1
  180. package/build/dist/Server/Types/Database/QueryHelper.js +17 -27
  181. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  182. package/build/dist/Server/Utils/Database/TruncateColumnValue.js +32 -0
  183. package/build/dist/Server/Utils/Database/TruncateColumnValue.js.map +1 -0
  184. package/build/dist/Types/CustomField/CustomFieldDefinition.js +2 -0
  185. package/build/dist/Types/CustomField/CustomFieldDefinition.js.map +1 -0
  186. package/build/dist/Types/Date.js +68 -0
  187. package/build/dist/Types/Date.js.map +1 -1
  188. package/build/dist/Types/Events/Recurring.js +63 -0
  189. package/build/dist/Types/Events/Recurring.js.map +1 -1
  190. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js +22 -0
  191. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js.map +1 -0
  192. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  193. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +18 -2
  194. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  195. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +213 -0
  196. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -0
  197. package/build/dist/UI/Utils/TeamMembersByUser.js +195 -0
  198. package/build/dist/UI/Utils/TeamMembersByUser.js.map +1 -0
  199. package/build/dist/Utils/StatusPage/ReportPeriod.js +131 -0
  200. package/build/dist/Utils/StatusPage/ReportPeriod.js.map +1 -0
  201. package/build/dist/Utils/Telemetry/HostIpAddresses.js +82 -0
  202. package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -0
  203. package/jest.config.json +2 -0
  204. package/package.json +1 -1
  205. package/tsconfig.json +12 -1
@@ -0,0 +1,131 @@
1
+ import OneUptimeDate from "../../Types/Date";
2
+ import EventInterval from "../../Types/Events/EventInterval";
3
+ import Recurring from "../../Types/Events/Recurring";
4
+ import StatusPageReportPeriodType from "../../Types/StatusPage/StatusPageReportPeriodType";
5
+ import Timezone from "../../Types/Timezone";
6
+ class StatusPageReportPeriodUtil {
7
+ static getDefaultPeriodType() {
8
+ return StatusPageReportPeriodType.Rolling;
9
+ }
10
+ /*
11
+ * Resolve the window a report sent at `sentAt` (default: now) covers.
12
+ *
13
+ * Everything is optional because this is called with a half-filled form as
14
+ * the user types, and with columns that are null on status pages created
15
+ * before reports were configurable. Missing values fall back to the same
16
+ * defaults the database columns carry.
17
+ */
18
+ static getReportPeriod(data) {
19
+ const timezone = data.timezone || this.DEFAULT_TIMEZONE;
20
+ const sentAt = data.sentAt || OneUptimeDate.getCurrentDate();
21
+ if (data.periodType === StatusPageReportPeriodType.PreviousCalendarPeriod) {
22
+ return this.getPreviousCalendarPeriod({
23
+ reportRecurringInterval: data.reportRecurringInterval,
24
+ timezone: timezone,
25
+ sentAt: sentAt,
26
+ });
27
+ }
28
+ return this.getRollingPeriod({
29
+ reportDataInDays: data.reportDataInDays,
30
+ timezone: timezone,
31
+ sentAt: sentAt,
32
+ });
33
+ }
34
+ static getRollingPeriod(data) {
35
+ const numberOfDays = this.toWholeDays(data.reportDataInDays, this.DEFAULT_REPORT_DATA_IN_DAYS);
36
+ const endDate = data.sentAt;
37
+ const startDate = OneUptimeDate.getSomeDaysAgoFromDate(endDate, numberOfDays);
38
+ return {
39
+ startDate: startDate,
40
+ endDate: endDate,
41
+ numberOfDays: numberOfDays,
42
+ timezone: data.timezone,
43
+ reportDates: `${numberOfDays} days (${this.formatDay(startDate, data.timezone)} - ${this.formatDay(endDate, data.timezone)})`,
44
+ periodName: numberOfDays === 1 ? "the last day" : `the last ${numberOfDays} days`,
45
+ };
46
+ }
47
+ /*
48
+ * The last WHOLE calendar period before the report went out, sized by the
49
+ * send frequency. A monthly report sent at any point in August covers
50
+ * 1 Aug 00:00:00.000 minus one month through 31 Jul 23:59:59.999 - i.e. July,
51
+ * exactly as it reads on a calendar, in the status page's report timezone.
52
+ */
53
+ static getPreviousCalendarPeriod(data) {
54
+ var _a;
55
+ const recurring = data.reportRecurringInterval
56
+ ? Recurring.fromJSON(data.reportRecurringInterval)
57
+ : Recurring.getDefault();
58
+ const unit = Recurring.toCalendarUnit(recurring.intervalType);
59
+ const intervalCount = this.toWholeDays((_a = recurring.intervalCount) === null || _a === void 0 ? void 0 : _a.toNumber(), 1);
60
+ /*
61
+ * Exclusive upper bound: the start of the period the report is being sent
62
+ * IN, which is the first instant not yet covered. The inclusive endDate
63
+ * below steps back a millisecond from it so the email reads "Jul 31" rather
64
+ * than "Aug 1".
65
+ */
66
+ const endExclusive = OneUptimeDate.getStartOfCalendarUnit(data.sentAt, unit, data.timezone);
67
+ const startDate = OneUptimeDate.addRemoveCalendarUnits(endExclusive, unit, -intervalCount, data.timezone);
68
+ const endDate = new Date(endExclusive.getTime() - 1);
69
+ return {
70
+ startDate: startDate,
71
+ endDate: endDate,
72
+ numberOfDays: Math.max(1, Math.round((endExclusive.getTime() - startDate.getTime()) /
73
+ OneUptimeDate.getMillisecondsInDays(1))),
74
+ timezone: data.timezone,
75
+ reportDates: `${this.formatDay(startDate, data.timezone)} - ${this.formatDay(endDate, data.timezone)}`,
76
+ periodName: this.getCalendarPeriodName({
77
+ intervalType: recurring.intervalType,
78
+ intervalCount: intervalCount,
79
+ startDate: startDate,
80
+ endDate: endDate,
81
+ timezone: data.timezone,
82
+ }),
83
+ };
84
+ }
85
+ static getCalendarPeriodName(data) {
86
+ /*
87
+ * Only a single-unit period has a name a reader already knows ("July 2026").
88
+ * Anything spanning several units, and hourly periods, are clearer as an
89
+ * explicit range.
90
+ */
91
+ if (data.intervalCount === 1) {
92
+ if (data.intervalType === EventInterval.Month) {
93
+ return this.format(data.startDate, "MMMM YYYY", data.timezone);
94
+ }
95
+ if (data.intervalType === EventInterval.Year) {
96
+ return this.format(data.startDate, "YYYY", data.timezone);
97
+ }
98
+ if (data.intervalType === EventInterval.Week) {
99
+ return `the week of ${this.formatDay(data.startDate, data.timezone)}`;
100
+ }
101
+ if (data.intervalType === EventInterval.Day) {
102
+ return this.formatDay(data.startDate, data.timezone);
103
+ }
104
+ }
105
+ return `${this.formatDay(data.startDate, data.timezone)} - ${this.formatDay(data.endDate, data.timezone)}`;
106
+ }
107
+ /*
108
+ * Guard against the nulls, decimals and zeroes a JSON column or a mid-edit
109
+ * form field can hold. A zero-length window would divide by zero downstream.
110
+ */
111
+ static toWholeDays(value, fallback) {
112
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
113
+ return fallback;
114
+ }
115
+ return Math.floor(value);
116
+ }
117
+ static formatDay(date, timezone) {
118
+ return this.format(date, "MMM D, YYYY", timezone);
119
+ }
120
+ static format(date, format, timezone) {
121
+ return OneUptimeDate.getDateAsCustomFormattedStringInTimezone({
122
+ date: date,
123
+ format: format,
124
+ timezone: timezone,
125
+ });
126
+ }
127
+ }
128
+ StatusPageReportPeriodUtil.DEFAULT_REPORT_DATA_IN_DAYS = 30;
129
+ StatusPageReportPeriodUtil.DEFAULT_TIMEZONE = Timezone.UTC;
130
+ export default StatusPageReportPeriodUtil;
131
+ //# sourceMappingURL=ReportPeriod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportPeriod.js","sourceRoot":"","sources":["../../../../Utils/StatusPage/ReportPeriod.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ /*
2
+ * Normalization for the OpenTelemetry `host.ip` resource attribute, which
3
+ * is an ARRAY of every address on every interface — not a single IP.
4
+ *
5
+ * On a Docker host with IPv6 enabled that array grows with the container
6
+ * count: the physical NIC, one address per docker bridge, one per veth,
7
+ * plus an IPv6 link-local per interface. 55 addresses / ~1450 characters
8
+ * has been observed in the wild (issue #3006), and there is no upper
9
+ * bound in the OTel spec.
10
+ *
11
+ * `Host.hostIpAddresses` is a `text` column so the realistic case is
12
+ * stored losslessly. These caps exist only so a pathological (or hostile)
13
+ * collector cannot push an unbounded blob into Postgres on every batch.
14
+ * They sit far above any plausible host, so in practice this function
15
+ * dedupes and joins and nothing else.
16
+ */
17
+ /** Maximum number of addresses retained. */
18
+ export const MAX_HOST_IP_ADDRESS_COUNT = 256;
19
+ /** Maximum length of the serialized, comma-separated list. */
20
+ export const MAX_HOST_IP_ADDRESSES_LENGTH = 10000;
21
+ const SEPARATOR = ", ";
22
+ /**
23
+ * Turn the raw `host.ip` values into the comma-separated string stored in
24
+ * `Host.hostIpAddresses`.
25
+ *
26
+ * - blank / whitespace-only entries are dropped,
27
+ * - each entry is trimmed,
28
+ * - duplicates are removed case-insensitively (IPv6 hex casing is not
29
+ * stable across resource detectors, so `FE80::1` and `fe80::1` are the
30
+ * same address),
31
+ * - source order is preserved — collectors report interfaces in a stable,
32
+ * meaningful order and reordering would churn the Hosts table column,
33
+ * - the result is capped by both address count and serialized length.
34
+ *
35
+ * Truncation always drops whole addresses from the tail. A half-written
36
+ * address would be worse than a missing one: it reads as a real address
37
+ * and there is no way for a consumer to tell it was cut.
38
+ *
39
+ * Returns `null` when nothing survives, so callers can leave the column
40
+ * untouched rather than writing an empty string.
41
+ */
42
+ export function normalizeHostIpAddresses(ipAddresses) {
43
+ if (!ipAddresses || ipAddresses.length === 0) {
44
+ return null;
45
+ }
46
+ const seen = new Set();
47
+ const kept = [];
48
+ let serializedLength = 0;
49
+ for (const raw of ipAddresses) {
50
+ if (typeof raw !== "string") {
51
+ continue;
52
+ }
53
+ const trimmed = raw.trim();
54
+ if (!trimmed) {
55
+ continue;
56
+ }
57
+ const dedupeKey = trimmed.toLowerCase();
58
+ if (seen.has(dedupeKey)) {
59
+ continue;
60
+ }
61
+ const lengthWithSeparator = trimmed.length + (kept.length > 0 ? SEPARATOR.length : 0);
62
+ if (serializedLength + lengthWithSeparator > MAX_HOST_IP_ADDRESSES_LENGTH) {
63
+ /*
64
+ * Stop rather than continue: entries are already ordered by the
65
+ * collector, so skipping this one to squeeze in a shorter later one
66
+ * would make the stored list order-dependent on address width.
67
+ */
68
+ break;
69
+ }
70
+ seen.add(dedupeKey);
71
+ kept.push(trimmed);
72
+ serializedLength += lengthWithSeparator;
73
+ if (kept.length >= MAX_HOST_IP_ADDRESS_COUNT) {
74
+ break;
75
+ }
76
+ }
77
+ if (kept.length === 0) {
78
+ return null;
79
+ }
80
+ return kept.join(SEPARATOR);
81
+ }
82
+ //# sourceMappingURL=HostIpAddresses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HostIpAddresses.js","sourceRoot":"","sources":["../../../../Utils/Telemetry/HostIpAddresses.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,4CAA4C;AAC5C,MAAM,CAAC,MAAM,yBAAyB,GAAW,GAAG,CAAC;AAErD,8DAA8D;AAC9D,MAAM,CAAC,MAAM,4BAA4B,GAAW,KAAK,CAAC;AAE1D,MAAM,SAAS,GAAW,IAAI,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;GAmBG;AACH,MAAM,UAAU,wBAAwB,CACtC,WAA6C;IAE7C,IAAI,CAAC,WAAW,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7C,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,IAAI,GAAgB,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,IAAI,GAAkB,EAAE,CAAC;IAC/B,IAAI,gBAAgB,GAAW,CAAC,CAAC;IAEjC,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,SAAS;QACX,CAAC;QAED,MAAM,OAAO,GAAW,GAAG,CAAC,IAAI,EAAE,CAAC;QACnC,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAW,OAAO,CAAC,WAAW,EAAE,CAAC;QAChD,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACxB,SAAS;QACX,CAAC;QAED,MAAM,mBAAmB,GACvB,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAE5D,IAAI,gBAAgB,GAAG,mBAAmB,GAAG,4BAA4B,EAAE,CAAC;YAC1E;;;;eAIG;YACH,MAAM;QACR,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACnB,gBAAgB,IAAI,mBAAmB,CAAC;QAExC,IAAI,IAAI,CAAC,MAAM,IAAI,yBAAyB,EAAE,CAAC;YAC7C,MAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAC9B,CAAC"}
package/jest.config.json CHANGED
@@ -10,6 +10,7 @@
10
10
  },
11
11
  "modulePathIgnorePatterns": ["<rootDir>/build/dist"],
12
12
  "moduleNameMapper": {
13
+ "\\.(svg|png|jpg|jpeg|gif|webp)$": "<rootDir>/Tests/__mocks__/styleMock.js",
13
14
  "Common/(.*)": "<rootDir>/$1",
14
15
  "\\.(css|less|scss|sass)$": "<rootDir>/Tests/__mocks__/styleMock.js",
15
16
  "^uuid$": "<rootDir>/Tests/__mocks__/uuid.js",
@@ -25,6 +26,7 @@
25
26
  "^react$": "<rootDir>/node_modules/react",
26
27
  "^react-dom$": "<rootDir>/node_modules/react-dom",
27
28
  "^react-dom/(.*)$": "<rootDir>/node_modules/react-dom/$1",
29
+ "^react-router-dom$": "<rootDir>/node_modules/react-router-dom",
28
30
  "^react-markdown$": "<rootDir>/Tests/__mocks__/react-markdown.js",
29
31
  "^remark-gfm$": "<rootDir>/Tests/__mocks__/remark-gfm.js",
30
32
  "^react-syntax-highlighter$": "<rootDir>/Tests/__mocks__/react-syntax-highlighter.js",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneuptime/common",
3
- "version": "12.0.1",
3
+ "version": "12.0.2",
4
4
  "description": "",
5
5
  "repository": {
6
6
  "type": "git",
package/tsconfig.json CHANGED
@@ -47,13 +47,24 @@
47
47
  * NOT in the Common Test CI job, which installs Common alone. The result
48
48
  * was a suite that passed locally and failed in CI.
49
49
  *
50
+ * "react-router-dom" is here for the same reason, one level out: those
51
+ * same Dashboard sources import it, and unlike "react" it is not covered
52
+ * by anything the type checker can already reach from Common. Node
53
+ * resolution walks up from the importing FILE, so from
54
+ * App/FeatureSet/Dashboard/src/... it only ever looks in App's and the
55
+ * repo root's node_modules - never in Common's, which in the Common Test
56
+ * CI job is the only one installed. Common's jest moduleNameMapper
57
+ * already maps this specifier to this same directory at runtime; this is
58
+ * the type checker's half of that.
59
+ *
50
60
  * Deliberately `paths` WITHOUT `baseUrl` (supported since TS 4.4, and
51
61
  * paths here are relative to this file). Setting baseUrl would change how
52
62
  * every bare specifier in Common resolves, which is a much larger blast
53
63
  * radius than this needs.
54
64
  */
55
65
  "paths": {
56
- "Common/*": ["./*"]
66
+ "Common/*": ["./*"],
67
+ "react-router-dom": ["./node_modules/react-router-dom"]
57
68
  },
58
69
  // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */
59
70
  "typeRoots": [