@oneuptime/common 12.0.7 → 12.0.8
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.
- package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
- package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
- package/Models/DatabaseModels/WorkflowLog.ts +38 -0
- package/Server/API/UserAPI.ts +16 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
- package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
- package/Server/Services/TelemetryEntityService.ts +114 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +44 -1
- package/Server/Types/Workflow/TriggerCode.ts +12 -0
- package/Server/Types/Workflow/Workflow.ts +5 -0
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
- package/Server/Utils/VM/VMAPI.ts +56 -8
- package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
- package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
- package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
- package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
- package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
- package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
- package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
- package/Tests/Types/Workflow/Templates.test.ts +403 -0
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
- package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
- package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
- package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
- package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +42 -0
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +90 -0
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +49 -7
- package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
- package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
- package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
- package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
- package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
- package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
- package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
- package/Types/SerializableObjectDictionary.ts +133 -39
- package/Types/Telemetry/EntitySource.ts +40 -0
- package/Types/Telemetry/EntityType.ts +27 -0
- package/Types/Telemetry/EntityTypeGroups.ts +65 -0
- package/Types/Workflow/Component.ts +29 -0
- package/Types/Workflow/Components/API.ts +35 -0
- package/Types/Workflow/Components/BaseModel.ts +7 -3
- package/Types/Workflow/StepTrace.ts +181 -0
- package/Types/Workflow/TemplateSyntax.ts +499 -0
- package/Types/Workflow/Templates.ts +316 -0
- package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
- package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
- package/UI/Components/Dictionary/Dictionary.tsx +23 -6
- package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
- package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
- package/UI/Components/Forms/Types/Field.ts +7 -0
- package/UI/Components/Forms/Validation.ts +63 -1
- package/UI/Components/Input/Input.tsx +31 -3
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
- package/UI/Components/Modal/Modal.tsx +37 -4
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
- package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
- package/UI/Components/Workflow/Component.tsx +28 -26
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
- package/UI/Components/Workflow/GraphLint.ts +591 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
- package/UI/Components/Workflow/ModelSchema.ts +196 -0
- package/UI/Components/Workflow/RunForm.tsx +41 -7
- package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
- package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
- package/UI/Components/Workflow/Utils.ts +93 -1
- package/UI/Components/Workflow/Workflow.tsx +77 -4
- package/UI/Types/LayeredDismissal.ts +31 -0
- package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
- package/Utils/Telemetry/EntityKey.ts +66 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +16 -1
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +28 -0
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +133 -39
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +39 -0
- package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +27 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
- package/build/dist/Types/Workflow/Component.js +21 -0
- package/build/dist/Types/Workflow/Component.js.map +1 -1
- package/build/dist/Types/Workflow/Components/API.js +35 -0
- package/build/dist/Types/Workflow/Components/API.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +7 -3
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/Types/Workflow/StepTrace.js +104 -0
- package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +218 -0
- package/build/dist/Types/Workflow/Templates.js.map +1 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
- package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +44 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +12 -4
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +31 -5
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +20 -19
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
- package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
- package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Utils.js +73 -1
- package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Types/LayeredDismissal.js +21 -0
- package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,507 @@
|
|
|
1
|
+
import TelemetryEntity from "../../../Models/DatabaseModels/TelemetryEntity";
|
|
2
|
+
import CloudResourceService from "../../Services/CloudResourceService";
|
|
3
|
+
import DockerHostService from "../../Services/DockerHostService";
|
|
4
|
+
import IoTDeviceService from "../../Services/IoTDeviceService";
|
|
5
|
+
import NetworkDeviceService from "../../Services/NetworkDeviceService";
|
|
6
|
+
import PodmanHostService from "../../Services/PodmanHostService";
|
|
7
|
+
import RumApplicationService from "../../Services/RumApplicationService";
|
|
8
|
+
import ServerlessFunctionService from "../../Services/ServerlessFunctionService";
|
|
9
|
+
import TelemetryEntityService from "../../Services/TelemetryEntityService";
|
|
10
|
+
import QueryHelper from "../../Types/Database/QueryHelper";
|
|
11
|
+
import ColumnLength from "../../../Types/Database/ColumnLength";
|
|
12
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
13
|
+
import OneUptimeDate from "../../../Types/Date";
|
|
14
|
+
import EntitySource from "../../../Types/Telemetry/EntitySource";
|
|
15
|
+
import EntityType from "../../../Types/Telemetry/EntityType";
|
|
16
|
+
import { INVENTORY_ENTITY_IDENTITY_ATTRIBUTE, keyForInventoryEntity, } from "../../../Utils/Telemetry/EntityKey";
|
|
17
|
+
import logger from "../Logger";
|
|
18
|
+
/*
|
|
19
|
+
* Mirrors OneUptime's inventory tables into the TelemetryEntity registry.
|
|
20
|
+
*
|
|
21
|
+
* The registry began as a projection of OTLP resource attributes, which is
|
|
22
|
+
* why the entity explorer shows a Kubernetes pod but not the switch next to
|
|
23
|
+
* it: half of what OneUptime inventories is collected by pollers (SNMP,
|
|
24
|
+
* cloud APIs, MQTT) that never produce a resource for ingest to extract
|
|
25
|
+
* entities from. Those rows already exist in rich typed tables — they were
|
|
26
|
+
* simply never projected. This module projects them, so "everything we know
|
|
27
|
+
* about the estate" is answerable in one query instead of eight.
|
|
28
|
+
*
|
|
29
|
+
* WHY A RECONCILE RATHER THAN CREATE/DELETE HOOKS ON EACH TABLE
|
|
30
|
+
*
|
|
31
|
+
* Hooks were the obvious approach and are the wrong one here, for three
|
|
32
|
+
* reasons that all bite the same way — a registry that silently disagrees
|
|
33
|
+
* with the inventory it mirrors:
|
|
34
|
+
*
|
|
35
|
+
* 1. Backfill. Hooks only fire on future writes, so every device
|
|
36
|
+
* registered before this shipped would stay invisible forever.
|
|
37
|
+
* 2. Cascade deletes. Deleting a project (or an IoT fleet) removes its
|
|
38
|
+
* devices by FK cascade, which fires no per-row service hook — the
|
|
39
|
+
* mirrored rows would outlive their owners.
|
|
40
|
+
* 3. Seven tables x two hooks is seven chances for a future edit to drop
|
|
41
|
+
* one, and the resulting drift is invisible until someone notices a
|
|
42
|
+
* device missing from the explorer.
|
|
43
|
+
*
|
|
44
|
+
* A periodic full reconcile is level-triggered: whatever the inventory
|
|
45
|
+
* says now is what the registry converges to, no matter how it got there.
|
|
46
|
+
* The cost is latency — a newly registered device appears within one cron
|
|
47
|
+
* period rather than instantly — which is an easy trade for inventory that
|
|
48
|
+
* changes on a human timescale.
|
|
49
|
+
*/
|
|
50
|
+
/** Registry rows are read and written in pages of this size. */
|
|
51
|
+
export const INVENTORY_SYNC_PAGE_SIZE = 1000;
|
|
52
|
+
/**
|
|
53
|
+
* Drops empty values so the stored attribute bag contains only things worth
|
|
54
|
+
* displaying — an inventory row with no OS recorded should have no `os.type`
|
|
55
|
+
* key rather than an empty one.
|
|
56
|
+
*/
|
|
57
|
+
export function compactAttributes(attributes) {
|
|
58
|
+
const out = {};
|
|
59
|
+
for (const key of Object.keys(attributes)) {
|
|
60
|
+
const value = attributes[key];
|
|
61
|
+
if (value === undefined || value === null) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const text = String(value).trim();
|
|
65
|
+
if (text.length === 0) {
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
out[key] = text;
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Builds the registry row for one inventory row. Pure: same inputs, same
|
|
74
|
+
* output, no database — this is the part worth testing exhaustively, since
|
|
75
|
+
* an identity mistake here is what would mint duplicate entities.
|
|
76
|
+
*/
|
|
77
|
+
export function buildInventoryEntityModel(data) {
|
|
78
|
+
const { source, row, now } = data;
|
|
79
|
+
const model = new TelemetryEntity();
|
|
80
|
+
model.projectId = row.projectId;
|
|
81
|
+
model.entityType = source.entityType;
|
|
82
|
+
model.entityKey = keyForInventoryEntity(row.projectId.toString(), source.entityType, row.id.toString());
|
|
83
|
+
model.source = EntitySource.Inventory;
|
|
84
|
+
/*
|
|
85
|
+
* Identity is the owning row's id, not its name: renaming a device in the
|
|
86
|
+
* UI must not orphan its registry row and mint a second one beside it.
|
|
87
|
+
*/
|
|
88
|
+
model.identifyingAttributes = {
|
|
89
|
+
[INVENTORY_ENTITY_IDENTITY_ATTRIBUTE]: row.id.toString(),
|
|
90
|
+
};
|
|
91
|
+
model.displayName = row.displayName.substring(0, ColumnLength.ShortText);
|
|
92
|
+
model.descriptiveAttributes = row.descriptiveAttributes;
|
|
93
|
+
/*
|
|
94
|
+
* The polymorphic pointer back to the rich typed row. Populated here for
|
|
95
|
+
* every mirrored type — previously only `service` entities carried one —
|
|
96
|
+
* so a registry row can be resolved to the page that owns it.
|
|
97
|
+
*/
|
|
98
|
+
model.resourceType = source.resourceType;
|
|
99
|
+
model.resourceId = row.id;
|
|
100
|
+
/*
|
|
101
|
+
* Both stamped at mirror time. `lastSeenAt` never advances for these rows
|
|
102
|
+
* (no telemetry heartbeat exists to advance it), which is precisely why
|
|
103
|
+
* PruneStaleEntities excludes EntitySource.Inventory.
|
|
104
|
+
*/
|
|
105
|
+
model.firstSeenAt = now;
|
|
106
|
+
model.lastSeenAt = now;
|
|
107
|
+
return model;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* True when a mirrored row has drifted from its owning inventory row and
|
|
111
|
+
* needs rewriting. Compared field by field rather than blindly updating so a
|
|
112
|
+
* steady-state reconcile issues no writes at all.
|
|
113
|
+
*/
|
|
114
|
+
export function inventoryEntityNeedsUpdate(data) {
|
|
115
|
+
var _a, _b;
|
|
116
|
+
const { existing, desired } = data;
|
|
117
|
+
if ((existing.displayName || "") !== (desired.displayName || "")) {
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
if (existing.resourceType !== desired.resourceType) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
if (((_a = existing.resourceId) === null || _a === void 0 ? void 0 : _a.toString()) !== ((_b = desired.resourceId) === null || _b === void 0 ? void 0 : _b.toString())) {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
return (JSON.stringify(existing.descriptiveAttributes || {}) !==
|
|
127
|
+
JSON.stringify(desired.descriptiveAttributes || {}));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* The columns a drifted mirror rewrites.
|
|
131
|
+
*
|
|
132
|
+
* Built as a plain shape and cast once, for the same two reasons as
|
|
133
|
+
* TelemetryEntityService.buildDescriptiveUpdate: assigning into
|
|
134
|
+
* `QueryDeepPartialEntity<TelemetryEntity>` directly makes TS instantiate the
|
|
135
|
+
* recursive JSONObject mapping (TS2589), and under this project's
|
|
136
|
+
* `exactOptionalPropertyTypes` an optional model field typed `string |
|
|
137
|
+
* undefined` is not assignable to the update type at all. Keys are therefore
|
|
138
|
+
* assigned only when they have a value rather than being set to undefined —
|
|
139
|
+
* which is also the correct write semantics: absent means "leave it alone",
|
|
140
|
+
* not "null it out".
|
|
141
|
+
*/
|
|
142
|
+
function buildMirrorUpdate(desired) {
|
|
143
|
+
const update = {};
|
|
144
|
+
if (desired.displayName !== undefined) {
|
|
145
|
+
update.displayName = desired.displayName;
|
|
146
|
+
}
|
|
147
|
+
if (desired.descriptiveAttributes !== undefined) {
|
|
148
|
+
update.descriptiveAttributes = desired.descriptiveAttributes;
|
|
149
|
+
}
|
|
150
|
+
if (desired.resourceType !== undefined) {
|
|
151
|
+
update.resourceType = desired.resourceType;
|
|
152
|
+
}
|
|
153
|
+
if (desired.resourceId !== undefined) {
|
|
154
|
+
update.resourceId = desired.resourceId;
|
|
155
|
+
}
|
|
156
|
+
return update;
|
|
157
|
+
}
|
|
158
|
+
function defineInventorySource(spec) {
|
|
159
|
+
return {
|
|
160
|
+
entityType: spec.entityType,
|
|
161
|
+
resourceType: spec.resourceType,
|
|
162
|
+
fetchPage: async (data) => {
|
|
163
|
+
const rows = await spec.service.findBy({
|
|
164
|
+
query: spec.query,
|
|
165
|
+
select: Object.assign({ _id: true, projectId: true, name: true }, spec.select),
|
|
166
|
+
skip: data.skip,
|
|
167
|
+
limit: data.limit,
|
|
168
|
+
props: { isRoot: true },
|
|
169
|
+
});
|
|
170
|
+
const projections = [];
|
|
171
|
+
for (const row of rows) {
|
|
172
|
+
const rowRecord = row;
|
|
173
|
+
const projectId = rowRecord["projectId"];
|
|
174
|
+
/*
|
|
175
|
+
* A row with no project cannot be mirrored — the entity key folds
|
|
176
|
+
* projectId in, and the registry is tenant-scoped. Should not occur;
|
|
177
|
+
* skipped rather than throwing so one bad row cannot stall the sweep.
|
|
178
|
+
*/
|
|
179
|
+
if (!row._id || !projectId) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
const name = rowRecord["name"];
|
|
183
|
+
const displayName = String(name || "").trim();
|
|
184
|
+
projections.push({
|
|
185
|
+
id: new ObjectID(row._id.toString()),
|
|
186
|
+
projectId: new ObjectID(String(projectId)),
|
|
187
|
+
displayName: displayName.length > 0 ? displayName : row._id.toString(),
|
|
188
|
+
descriptiveAttributes: spec.describe(row),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return projections;
|
|
192
|
+
},
|
|
193
|
+
findLiveIds: async (ids) => {
|
|
194
|
+
if (ids.length === 0) {
|
|
195
|
+
return new Set();
|
|
196
|
+
}
|
|
197
|
+
/*
|
|
198
|
+
* Deliberately unfiltered by `spec.query`: this answers "does the row
|
|
199
|
+
* still exist", and an archived row still exists. Reusing the mirror
|
|
200
|
+
* query here would make archiving delete the registry row rather than
|
|
201
|
+
* merely stop refreshing it, which is a different (and destructive)
|
|
202
|
+
* behaviour from the one intended.
|
|
203
|
+
*/
|
|
204
|
+
const rows = await spec.service.findBy({
|
|
205
|
+
query: {
|
|
206
|
+
_id: QueryHelper.any(ids.map((id) => {
|
|
207
|
+
return id.toString();
|
|
208
|
+
})),
|
|
209
|
+
},
|
|
210
|
+
select: { _id: true },
|
|
211
|
+
skip: 0,
|
|
212
|
+
limit: ids.length,
|
|
213
|
+
props: { isRoot: true },
|
|
214
|
+
});
|
|
215
|
+
return new Set(rows.map((row) => {
|
|
216
|
+
return row._id.toString();
|
|
217
|
+
}));
|
|
218
|
+
},
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
/*
|
|
222
|
+
* Archived rows are excluded from every source that has the concept: the
|
|
223
|
+
* explorer is a view of the live estate. IoTDevice and NetworkDevice have no
|
|
224
|
+
* archive flag, so their queries are unrestricted.
|
|
225
|
+
*/
|
|
226
|
+
export const INVENTORY_SOURCES = [
|
|
227
|
+
defineInventorySource({
|
|
228
|
+
entityType: EntityType.NetworkDevice,
|
|
229
|
+
resourceType: "NetworkDevice",
|
|
230
|
+
service: NetworkDeviceService,
|
|
231
|
+
select: { hostname: true },
|
|
232
|
+
query: {},
|
|
233
|
+
describe: (row) => {
|
|
234
|
+
return compactAttributes({ "net.device.hostname": row.hostname });
|
|
235
|
+
},
|
|
236
|
+
}),
|
|
237
|
+
defineInventorySource({
|
|
238
|
+
entityType: EntityType.CloudResource,
|
|
239
|
+
resourceType: "CloudResource",
|
|
240
|
+
service: CloudResourceService,
|
|
241
|
+
select: {
|
|
242
|
+
resourceIdentifier: true,
|
|
243
|
+
cloudProvider: true,
|
|
244
|
+
cloudRegion: true,
|
|
245
|
+
cloudAccountId: true,
|
|
246
|
+
},
|
|
247
|
+
query: { isArchived: false },
|
|
248
|
+
describe: (row) => {
|
|
249
|
+
return compactAttributes({
|
|
250
|
+
"cloud.resource.id": row.resourceIdentifier,
|
|
251
|
+
"cloud.provider": row.cloudProvider,
|
|
252
|
+
"cloud.region": row.cloudRegion,
|
|
253
|
+
"cloud.account.id": row.cloudAccountId,
|
|
254
|
+
});
|
|
255
|
+
},
|
|
256
|
+
}),
|
|
257
|
+
defineInventorySource({
|
|
258
|
+
entityType: EntityType.ServerlessFunction,
|
|
259
|
+
resourceType: "ServerlessFunction",
|
|
260
|
+
service: ServerlessFunctionService,
|
|
261
|
+
select: {
|
|
262
|
+
functionIdentifier: true,
|
|
263
|
+
cloudProvider: true,
|
|
264
|
+
cloudRegion: true,
|
|
265
|
+
runtimeName: true,
|
|
266
|
+
},
|
|
267
|
+
query: { isArchived: false },
|
|
268
|
+
describe: (row) => {
|
|
269
|
+
return compactAttributes({
|
|
270
|
+
"faas.name": row.functionIdentifier,
|
|
271
|
+
"cloud.provider": row.cloudProvider,
|
|
272
|
+
"cloud.region": row.cloudRegion,
|
|
273
|
+
"process.runtime.name": row.runtimeName,
|
|
274
|
+
});
|
|
275
|
+
},
|
|
276
|
+
}),
|
|
277
|
+
defineInventorySource({
|
|
278
|
+
entityType: EntityType.RumApplication,
|
|
279
|
+
resourceType: "RumApplication",
|
|
280
|
+
service: RumApplicationService,
|
|
281
|
+
select: { appIdentifier: true, clientType: true, sdkLanguage: true },
|
|
282
|
+
query: { isArchived: false },
|
|
283
|
+
describe: (row) => {
|
|
284
|
+
return compactAttributes({
|
|
285
|
+
"rum.app.id": row.appIdentifier,
|
|
286
|
+
"rum.client.type": row.clientType,
|
|
287
|
+
"telemetry.sdk.language": row.sdkLanguage,
|
|
288
|
+
});
|
|
289
|
+
},
|
|
290
|
+
}),
|
|
291
|
+
defineInventorySource({
|
|
292
|
+
entityType: EntityType.IoTDevice,
|
|
293
|
+
resourceType: "IoTDevice",
|
|
294
|
+
service: IoTDeviceService,
|
|
295
|
+
select: { externalId: true, deviceType: true, firmwareVersion: true },
|
|
296
|
+
query: {},
|
|
297
|
+
describe: (row) => {
|
|
298
|
+
return compactAttributes({
|
|
299
|
+
"device.id": row.externalId,
|
|
300
|
+
"device.type": row.deviceType,
|
|
301
|
+
"device.firmware.version": row.firmwareVersion,
|
|
302
|
+
});
|
|
303
|
+
},
|
|
304
|
+
}),
|
|
305
|
+
defineInventorySource({
|
|
306
|
+
entityType: EntityType.DockerHost,
|
|
307
|
+
resourceType: "DockerHost",
|
|
308
|
+
service: DockerHostService,
|
|
309
|
+
select: { hostIdentifier: true, osType: true, osVersion: true },
|
|
310
|
+
query: { isArchived: false },
|
|
311
|
+
describe: (row) => {
|
|
312
|
+
return compactAttributes({
|
|
313
|
+
"host.name": row.hostIdentifier,
|
|
314
|
+
"os.type": row.osType,
|
|
315
|
+
"os.version": row.osVersion,
|
|
316
|
+
});
|
|
317
|
+
},
|
|
318
|
+
}),
|
|
319
|
+
defineInventorySource({
|
|
320
|
+
entityType: EntityType.PodmanHost,
|
|
321
|
+
resourceType: "PodmanHost",
|
|
322
|
+
service: PodmanHostService,
|
|
323
|
+
select: { hostIdentifier: true, osType: true, osVersion: true },
|
|
324
|
+
query: { isArchived: false },
|
|
325
|
+
describe: (row) => {
|
|
326
|
+
return compactAttributes({
|
|
327
|
+
"host.name": row.hostIdentifier,
|
|
328
|
+
"os.type": row.osType,
|
|
329
|
+
"os.version": row.osVersion,
|
|
330
|
+
});
|
|
331
|
+
},
|
|
332
|
+
}),
|
|
333
|
+
];
|
|
334
|
+
/**
|
|
335
|
+
* Forward pass: every live inventory row gets a registry row, and one that
|
|
336
|
+
* has drifted (renamed, re-tagged) is rewritten.
|
|
337
|
+
*/
|
|
338
|
+
async function mirrorRows(source) {
|
|
339
|
+
let created = 0;
|
|
340
|
+
let updated = 0;
|
|
341
|
+
let skip = 0;
|
|
342
|
+
for (;;) {
|
|
343
|
+
const rows = await source.fetchPage({
|
|
344
|
+
skip,
|
|
345
|
+
limit: INVENTORY_SYNC_PAGE_SIZE,
|
|
346
|
+
});
|
|
347
|
+
if (rows.length === 0) {
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
const now = OneUptimeDate.getCurrentDate();
|
|
351
|
+
const desiredByKey = new Map();
|
|
352
|
+
for (const row of rows) {
|
|
353
|
+
const model = buildInventoryEntityModel({
|
|
354
|
+
source,
|
|
355
|
+
row,
|
|
356
|
+
now,
|
|
357
|
+
});
|
|
358
|
+
desiredByKey.set(model.entityKey, model);
|
|
359
|
+
}
|
|
360
|
+
const existingRows = await TelemetryEntityService.findBy({
|
|
361
|
+
query: {
|
|
362
|
+
entityType: source.entityType,
|
|
363
|
+
entityKey: QueryHelper.any(Array.from(desiredByKey.keys())),
|
|
364
|
+
},
|
|
365
|
+
select: {
|
|
366
|
+
_id: true,
|
|
367
|
+
entityKey: true,
|
|
368
|
+
displayName: true,
|
|
369
|
+
descriptiveAttributes: true,
|
|
370
|
+
resourceType: true,
|
|
371
|
+
resourceId: true,
|
|
372
|
+
},
|
|
373
|
+
skip: 0,
|
|
374
|
+
limit: desiredByKey.size,
|
|
375
|
+
props: { isRoot: true },
|
|
376
|
+
});
|
|
377
|
+
const existingByKey = new Map();
|
|
378
|
+
for (const existing of existingRows) {
|
|
379
|
+
existingByKey.set(existing.entityKey, existing);
|
|
380
|
+
}
|
|
381
|
+
for (const [key, desired] of desiredByKey.entries()) {
|
|
382
|
+
const existing = existingByKey.get(key);
|
|
383
|
+
try {
|
|
384
|
+
if (!existing) {
|
|
385
|
+
await TelemetryEntityService.create({
|
|
386
|
+
data: desired,
|
|
387
|
+
props: { isRoot: true },
|
|
388
|
+
});
|
|
389
|
+
created++;
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
if (inventoryEntityNeedsUpdate({ existing, desired })) {
|
|
393
|
+
await TelemetryEntityService.updateOneById({
|
|
394
|
+
id: existing.id,
|
|
395
|
+
data: buildMirrorUpdate(desired),
|
|
396
|
+
props: { isRoot: true },
|
|
397
|
+
});
|
|
398
|
+
updated++;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
catch (err) {
|
|
402
|
+
/*
|
|
403
|
+
* One unmirrorable row must not stall the rest of the estate. The
|
|
404
|
+
* next run retries it, so a transient failure self-heals.
|
|
405
|
+
*/
|
|
406
|
+
logger.error(`InventoryEntityRegistry: failed to mirror ${source.resourceType} row for entity key ${key}:`);
|
|
407
|
+
logger.error(err);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
skip += rows.length;
|
|
411
|
+
if (rows.length < INVENTORY_SYNC_PAGE_SIZE) {
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return { created, updated };
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Reverse pass: a mirrored row whose owning inventory row is gone is
|
|
419
|
+
* deleted. This is what catches cascade deletes, which fire no service hook.
|
|
420
|
+
*/
|
|
421
|
+
async function removeOrphans(source) {
|
|
422
|
+
const orphanIds = [];
|
|
423
|
+
let skip = 0;
|
|
424
|
+
/*
|
|
425
|
+
* Collected across a read-only pass and deleted afterwards. Deleting while
|
|
426
|
+
* paging would shift subsequent offsets and skip rows.
|
|
427
|
+
*/
|
|
428
|
+
for (;;) {
|
|
429
|
+
const rows = await TelemetryEntityService.findBy({
|
|
430
|
+
query: {
|
|
431
|
+
entityType: source.entityType,
|
|
432
|
+
source: EntitySource.Inventory,
|
|
433
|
+
},
|
|
434
|
+
select: { _id: true, resourceId: true },
|
|
435
|
+
skip,
|
|
436
|
+
limit: INVENTORY_SYNC_PAGE_SIZE,
|
|
437
|
+
props: { isRoot: true },
|
|
438
|
+
});
|
|
439
|
+
if (rows.length === 0) {
|
|
440
|
+
break;
|
|
441
|
+
}
|
|
442
|
+
const resourceIds = [];
|
|
443
|
+
for (const row of rows) {
|
|
444
|
+
if (row.resourceId) {
|
|
445
|
+
resourceIds.push(row.resourceId);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
const liveIds = await source.findLiveIds(resourceIds);
|
|
449
|
+
for (const row of rows) {
|
|
450
|
+
/*
|
|
451
|
+
* A mirrored row with no pointer cannot be matched back to anything,
|
|
452
|
+
* so it is orphaned by definition.
|
|
453
|
+
*/
|
|
454
|
+
if (!row.resourceId || !liveIds.has(row.resourceId.toString())) {
|
|
455
|
+
orphanIds.push(row.id);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
skip += rows.length;
|
|
459
|
+
if (rows.length < INVENTORY_SYNC_PAGE_SIZE) {
|
|
460
|
+
break;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (orphanIds.length === 0) {
|
|
464
|
+
return 0;
|
|
465
|
+
}
|
|
466
|
+
await TelemetryEntityService.hardDeleteBy({
|
|
467
|
+
query: {
|
|
468
|
+
_id: QueryHelper.any(orphanIds.map((id) => {
|
|
469
|
+
return id.toString();
|
|
470
|
+
})),
|
|
471
|
+
// Re-asserted so a bug upstream can never widen this into a broad delete.
|
|
472
|
+
source: EntitySource.Inventory,
|
|
473
|
+
},
|
|
474
|
+
limit: orphanIds.length,
|
|
475
|
+
skip: 0,
|
|
476
|
+
props: { isRoot: true },
|
|
477
|
+
});
|
|
478
|
+
return orphanIds.length;
|
|
479
|
+
}
|
|
480
|
+
/** Reconciles one inventory table into the registry. */
|
|
481
|
+
export async function syncInventorySource(source) {
|
|
482
|
+
const { created, updated } = await mirrorRows(source);
|
|
483
|
+
const deleted = await removeOrphans(source);
|
|
484
|
+
return { created, updated, deleted };
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Reconciles every inventory table. Each source is isolated: a failure in
|
|
488
|
+
* one leaves the others to complete, because a broken cloud integration
|
|
489
|
+
* should not stop network devices being mirrored.
|
|
490
|
+
*/
|
|
491
|
+
export async function syncAllInventorySources() {
|
|
492
|
+
const total = { created: 0, updated: 0, deleted: 0 };
|
|
493
|
+
for (const source of INVENTORY_SOURCES) {
|
|
494
|
+
try {
|
|
495
|
+
const result = await syncInventorySource(source);
|
|
496
|
+
total.created += result.created;
|
|
497
|
+
total.updated += result.updated;
|
|
498
|
+
total.deleted += result.deleted;
|
|
499
|
+
}
|
|
500
|
+
catch (err) {
|
|
501
|
+
logger.error(`InventoryEntityRegistry: sync failed for ${source.resourceType}:`);
|
|
502
|
+
logger.error(err);
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
return total;
|
|
506
|
+
}
|
|
507
|
+
//# sourceMappingURL=InventoryEntityRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InventoryEntityRegistry.js","sourceRoot":"","sources":["../../../../../Server/Utils/Telemetry/InventoryEntityRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -26,12 +26,25 @@ export default class VMUtil {
|
|
|
26
26
|
return valueToReplaceInPlace;
|
|
27
27
|
}
|
|
28
28
|
}
|
|
29
|
+
/*
|
|
30
|
+
* When we stringified the value ourselves just above, every placeholder in
|
|
31
|
+
* the text we are about to substitute into sits inside a JSON string
|
|
32
|
+
* literal — that is what JSON.stringify did to it. A resolved value
|
|
33
|
+
* carrying a quote or a newline therefore has to be escaped, or the
|
|
34
|
+
* JSON.parse at the bottom of this method fails and the caller silently
|
|
35
|
+
* receives a corrupted string where it asked for an object.
|
|
36
|
+
*
|
|
37
|
+
* This is separate from the caller's isJSON flag, which describes text the
|
|
38
|
+
* caller wrote and where a placeholder may legitimately stand in for a bare
|
|
39
|
+
* JSON value rather than sit inside a string.
|
|
40
|
+
*/
|
|
41
|
+
const shouldEscapeForJSON = Boolean(isJSON) || didStringify;
|
|
29
42
|
if (typeof valueToReplaceInPlace === "string" &&
|
|
30
43
|
valueToReplaceInPlace.toString().includes("{{") &&
|
|
31
44
|
valueToReplaceInPlace.toString().includes("}}")) {
|
|
32
45
|
let valueToReplaceInPlaceCopy = valueToReplaceInPlace.toString();
|
|
33
46
|
// First, expand {{#each path}}...{{/each}} loops before variable substitution
|
|
34
|
-
valueToReplaceInPlaceCopy = VMUtil.expandEachLoops(storageMap, valueToReplaceInPlaceCopy,
|
|
47
|
+
valueToReplaceInPlaceCopy = VMUtil.expandEachLoops(storageMap, valueToReplaceInPlaceCopy, shouldEscapeForJSON);
|
|
35
48
|
const variablesInArgument = [];
|
|
36
49
|
const regex = /{{(.*?)}}/g; // Find all matches of the regular expression and capture the word between the braces {{x}} => x
|
|
37
50
|
let match = null;
|
|
@@ -58,9 +71,18 @@ export default class VMUtil {
|
|
|
58
71
|
valueToReplaceInPlaceCopy = valueToReplaceInPlace;
|
|
59
72
|
}
|
|
60
73
|
else {
|
|
61
|
-
|
|
74
|
+
const replacement = shouldEscapeForJSON
|
|
62
75
|
? VMUtil.serializeValueForJSON(valueToReplaceInPlace)
|
|
63
|
-
: `${valueToReplaceInPlace}
|
|
76
|
+
: `${valueToReplaceInPlace}`;
|
|
77
|
+
/*
|
|
78
|
+
* Function form, not the string form. String.replace treats $&, $1,
|
|
79
|
+
* $` and $' in the REPLACEMENT as substitution patterns, so a
|
|
80
|
+
* resolved value of "50$" or "a$&b" rewrote itself using the matched
|
|
81
|
+
* text. A function replacement is taken literally.
|
|
82
|
+
*/
|
|
83
|
+
valueToReplaceInPlaceCopy = valueToReplaceInPlaceCopy.replace("{{" + variable + "}}", () => {
|
|
84
|
+
return replacement;
|
|
85
|
+
});
|
|
64
86
|
}
|
|
65
87
|
}
|
|
66
88
|
valueToReplaceInPlace = valueToReplaceInPlaceCopy;
|
|
@@ -211,7 +233,13 @@ export default class VMUtil {
|
|
|
211
233
|
else {
|
|
212
234
|
replacement = `${foundValue}`;
|
|
213
235
|
}
|
|
214
|
-
|
|
236
|
+
const substitution = isJSON
|
|
237
|
+
? VMUtil.serializeValueForJSON(replacement)
|
|
238
|
+
: replacement;
|
|
239
|
+
// Function form — see the note on the same call in replaceValueInPlace.
|
|
240
|
+
body = body.replace("{{" + variable + "}}", () => {
|
|
241
|
+
return substitution;
|
|
242
|
+
});
|
|
215
243
|
}
|
|
216
244
|
return body;
|
|
217
245
|
}
|
|
@@ -224,6 +252,15 @@ export default class VMUtil {
|
|
|
224
252
|
}
|
|
225
253
|
else {
|
|
226
254
|
value = value
|
|
255
|
+
/*
|
|
256
|
+
* Backslash first, and only first. It was missing entirely, so a value
|
|
257
|
+
* like a Windows path or a regex ("C:\Users", "\d+") produced an
|
|
258
|
+
* invalid escape sequence in the surrounding document and the
|
|
259
|
+
* JSON.parse that followed threw. Escaping it after the others would
|
|
260
|
+
* instead double-escape the backslashes they just introduced.
|
|
261
|
+
*/
|
|
262
|
+
.split("\\")
|
|
263
|
+
.join("\\\\")
|
|
227
264
|
.split("\t")
|
|
228
265
|
.join("\\t")
|
|
229
266
|
.split("\n")
|
|
@@ -257,6 +294,16 @@ export default class VMUtil {
|
|
|
257
294
|
index = parseInt(indexString);
|
|
258
295
|
}
|
|
259
296
|
else {
|
|
297
|
+
/*
|
|
298
|
+
* `current[arrayKey].length` was read unguarded, so `items[last]`
|
|
299
|
+
* against a key that is missing (or is not an array) threw a
|
|
300
|
+
* TypeError out of deepFind and killed the entire run — the one
|
|
301
|
+
* resolution failure in here that was not silent. Fall through to the
|
|
302
|
+
* undefined return that every other miss produces.
|
|
303
|
+
*/
|
|
304
|
+
if (!Array.isArray(current[arrayKey])) {
|
|
305
|
+
return undefined;
|
|
306
|
+
}
|
|
260
307
|
index = current[arrayKey].length - 1;
|
|
261
308
|
}
|
|
262
309
|
if (Array.isArray(current[arrayKey]) && current[arrayKey][index]) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VMAPI.js","sourceRoot":"","sources":["../../../../../Server/Utils/VM/VMAPI.ts"],"names":[],"mappings":";;;;;;;;;AAEA,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,OAAO,OAAO,MAAM;IAEL,AAAb,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAMpC;QACC,OAAO,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAGa,AAAP,MAAM,CAAC,mBAAmB,CAC/B,UAAsB,EACtB,qBAA6B,EAC7B,MAA2B;QAE3B,IAAI,YAAY,GAAY,KAAK,CAAC;QAElC,IAAI,OAAO,qBAAqB,KAAK,QAAQ,EAAE,CAAC;YAC9C,IAAI,CAAC;gBACH,qBAAqB,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;gBAC9D,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAClB,OAAO,qBAAqB,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,IACE,OAAO,qBAAqB,KAAK,QAAQ;YACzC,qBAAqB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC/C,qBAAqB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC/C,CAAC;YACD,IAAI,yBAAyB,GAAW,qBAAqB,CAAC,QAAQ,EAAE,CAAC;YAEzE,8EAA8E;YAC9E,yBAAyB,GAAG,MAAM,CAAC,eAAe,CAChD,UAAU,EACV,yBAAyB,EACzB,
|
|
1
|
+
{"version":3,"file":"VMAPI.js","sourceRoot":"","sources":["../../../../../Server/Utils/VM/VMAPI.ts"],"names":[],"mappings":";;;;;;;;;AAEA,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,WAAW,MAAM,0BAA0B,CAAC;AACnD,OAAO,QAAQ,MAAM,YAAY,CAAC;AAElC,MAAM,CAAC,OAAO,OAAO,MAAM;IAEL,AAAb,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,IAMpC;QACC,OAAO,QAAQ,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACzC,CAAC;IAGa,AAAP,MAAM,CAAC,mBAAmB,CAC/B,UAAsB,EACtB,qBAA6B,EAC7B,MAA2B;QAE3B,IAAI,YAAY,GAAY,KAAK,CAAC;QAElC,IAAI,OAAO,qBAAqB,KAAK,QAAQ,EAAE,CAAC;YAC9C,IAAI,CAAC;gBACH,qBAAqB,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;gBAC9D,YAAY,GAAG,IAAI,CAAC;YACtB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAClB,OAAO,qBAAqB,CAAC;YAC/B,CAAC;QACH,CAAC;QAED;;;;;;;;;;;WAWG;QACH,MAAM,mBAAmB,GAAY,OAAO,CAAC,MAAM,CAAC,IAAI,YAAY,CAAC;QAErE,IACE,OAAO,qBAAqB,KAAK,QAAQ;YACzC,qBAAqB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC;YAC/C,qBAAqB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC/C,CAAC;YACD,IAAI,yBAAyB,GAAW,qBAAqB,CAAC,QAAQ,EAAE,CAAC;YAEzE,8EAA8E;YAC9E,yBAAyB,GAAG,MAAM,CAAC,eAAe,CAChD,UAAU,EACV,yBAAyB,EACzB,mBAAmB,CACpB,CAAC;YAEF,MAAM,mBAAmB,GAAkB,EAAE,CAAC;YAE9C,MAAM,KAAK,GAAW,YAAY,CAAC,CAAC,gGAAgG;YAEpI,IAAI,KAAK,GAA2B,IAAI,CAAC;YAEzC,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAChE,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;oBACb,mBAAmB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC;YAED,KAAK,MAAM,QAAQ,IAAI,mBAAmB,EAAE,CAAC;gBAC3C,MAAM,UAAU,GAAc,MAAM,CAAC,QAAQ,CAC3C,UAAiB,EACjB,QAAe,CAChB,CAAC;gBAEF,mEAAmE;gBACnE,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;oBAC7B,SAAS;gBACX,CAAC;gBAED,IAAI,qBAA6B,CAAC;gBAElC,6CAA6C;gBAC7C,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;oBAC1D,qBAAqB,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC9D,CAAC;qBAAM,CAAC;oBACN,qBAAqB,GAAG,UAAoB,CAAC;gBAC/C,CAAC;gBAED,IAAI,yBAAyB,CAAC,IAAI,EAAE,KAAK,IAAI,GAAG,QAAQ,GAAG,IAAI,EAAE,CAAC;oBAChE,yBAAyB,GAAG,qBAAqB,CAAC;gBACpD,CAAC;qBAAM,CAAC;oBACN,MAAM,WAAW,GAAW,mBAAmB;wBAC7C,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,qBAAqB,CAAC;wBACrD,CAAC,CAAC,GAAG,qBAAqB,EAAE,CAAC;oBAE/B;;;;;uBAKG;oBACH,yBAAyB,GAAG,yBAAyB,CAAC,OAAO,CAC3D,IAAI,GAAG,QAAQ,GAAG,IAAI,EACtB,GAAG,EAAE;wBACH,OAAO,WAAW,CAAC;oBACrB,CAAC,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,qBAAqB,GAAG,yBAAyB,CAAC;QACpD,CAAC;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,IAAI,CAAC;gBACH,qBAAqB,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAClB,OAAO,qBAAqB,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;;;;OAcG;IAEW,AAAP,MAAM,CAAC,eAAe,CAC3B,UAAsB,EACtB,QAAgB,EAChB,MAA2B;QAE3B,IAAI,MAAM,GAAW,QAAQ,CAAC;QAC9B,MAAM,aAAa,GAAW,GAAG,CAAC,CAAC,yCAAyC;QAC5E,IAAI,UAAU,GAAW,CAAC,CAAC;QAE3B,OAAO,UAAU,GAAG,aAAa,EAAE,CAAC;YAClC,UAAU,EAAE,CAAC;YAEb,+CAA+C;YAC/C,MAAM,OAAO,GAAW,uBAAuB,CAAC;YAChD,MAAM,SAAS,GAA2B,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAE/D,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,CAAC,2BAA2B;YACpC,CAAC;YAED,MAAM,UAAU,GAAW,SAAS,CAAC,KAAM,CAAC;YAC5C,MAAM,SAAS,GAAW,SAAS,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,CAAC;YAC/C,MAAM,SAAS,GAAW,UAAU,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC;YAE5D,wDAAwD;YACxD,IAAI,KAAK,GAAW,CAAC,CAAC;YACtB,IAAI,SAAS,GAAW,SAAS,CAAC;YAClC,IAAI,QAAQ,GAAW,CAAC,CAAC,CAAC;YAC1B,IAAI,OAAO,GAAW,CAAC,CAAC,CAAC;YAEzB,OAAO,KAAK,GAAG,CAAC,IAAI,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC9C,MAAM,QAAQ,GAAW,MAAM,CAAC,OAAO,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;gBAC/D,MAAM,SAAS,GAAW,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;gBAEjE,IAAI,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;oBACrB,yDAAyD;oBACzD,MAAM;gBACR,CAAC;gBAED,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,QAAQ,GAAG,SAAS,EAAE,CAAC;oBAC5C,qDAAqD;oBACrD,KAAK,EAAE,CAAC;oBACR,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,uBAAuB;gBACnD,CAAC;qBAAM,CAAC;oBACN,kBAAkB;oBAClB,KAAK,EAAE,CAAC;oBACR,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;wBAChB,OAAO,GAAG,SAAS,CAAC;wBACpB,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC;oBAC5C,CAAC;oBACD,SAAS,GAAG,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC;gBAC7C,CAAC;YACH,CAAC;YAED,IAAI,QAAQ,KAAK,CAAC,CAAC,IAAI,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC;gBACtC,2DAA2D;gBAC3D,MAAM;oBACJ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;wBAC3B,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC,CAAE,CAAC,MAAM,CAAC,CAAC;gBAClD,SAAS;YACX,CAAC;YAED,MAAM,QAAQ,GAAW,MAAM,CAAC,KAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;YAE1D,yCAAyC;YACzC,MAAM,UAAU,GAAc,MAAM,CAAC,QAAQ,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;YAErE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,2CAA2C;gBAC3C,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;gBAC9D,SAAS;YACX,CAAC;YAED,qDAAqD;YACrD,MAAM,aAAa,GAAkB,EAAE,CAAC;YAExC,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACnD,MAAM,OAAO,GAAc,UAAU,CAAC,CAAC,CAAE,CAAC;gBAC1C,IAAI,aAAa,GAAW,QAAQ,CAAC;gBAErC,4CAA4C;gBAC5C,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEvE,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;oBACpD;;;;uBAIG;oBACH,MAAM,gBAAgB,mCACjB,UAAU,GACT,OAAsB,CAC3B,CAAC;oBAEF,2EAA2E;oBAC3E,aAAa,GAAG,MAAM,CAAC,eAAe,CACpC,gBAAgB,EAChB,aAAa,EACb,MAAM,CACP,CAAC;oBAEF,8CAA8C;oBAC9C,aAAa,GAAG,MAAM,CAAC,oBAAoB,CACzC,OAAqB,EACrB,UAAU,EACV,aAAa,EACb,MAAM,CACP,CAAC;gBACJ,CAAC;qBAAM,CAAC;oBACN,gEAAgE;oBAChE,aAAa,GAAG,aAAa,CAAC,OAAO,CACnC,eAAe,EACf,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,GAAG,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,EAAE,CACnE,CAAC;gBACJ,CAAC;gBAED,aAAa,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC;YAED,MAAM;gBACJ,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC;oBAC3B,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;oBACtB,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC3B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IAEY,AAAP,MAAM,CAAC,oBAAoB,CACjC,OAAmB,EACnB,gBAA4B,EAC5B,IAAY,EACZ,MAA2B;QAE3B,MAAM,aAAa,GAAW,6CAA6C,CAAC;QAC5E,IAAI,KAAK,GAA2B,IAAI,CAAC;QACzC,MAAM,SAAS,GAAkB,EAAE,CAAC;QAEpC,OAAO,CAAC,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACnD,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACb,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,sDAAsD;YACtD,IAAI,UAAU,GAAc,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAEtE,2DAA2D;YAC3D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,UAAU,GAAG,MAAM,CAAC,QAAQ,CAAC,gBAAgB,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;YAClE,CAAC;YAED,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;gBAC7B,SAAS,CAAC,mBAAmB;YAC/B,CAAC;YAED,IAAI,WAAmB,CAAC;YAExB,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;gBAC1D,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YACpD,CAAC;iBAAM,CAAC;gBACN,WAAW,GAAG,GAAG,UAAU,EAAE,CAAC;YAChC,CAAC;YAED,MAAM,YAAY,GAAW,MAAM;gBACjC,CAAC,CAAC,MAAM,CAAC,qBAAqB,CAAC,WAAW,CAAC;gBAC3C,CAAC,CAAC,WAAW,CAAC;YAEhB,wEAAwE;YACxE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,QAAQ,GAAG,IAAI,EAAE,GAAG,EAAE;gBAC/C,OAAO,YAAY,CAAC;YACtB,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC;IAGa,AAAP,MAAM,CAAC,qBAAqB,CAAC,KAAa;QAC/C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,KAAK,CAAC;QACf,CAAC;QAED,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,KAAK,GAAG,KAAK;gBACX;;;;;;mBAMG;iBACF,KAAK,CAAC,IAAI,CAAC;iBACX,IAAI,CAAC,MAAM,CAAC;iBACZ,KAAK,CAAC,IAAI,CAAC;iBACX,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,IAAI,CAAC;iBACX,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,IAAI,CAAC;iBACX,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,IAAI,CAAC;iBACX,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,IAAI,CAAC;iBACX,IAAI,CAAC,KAAK,CAAC;iBACX,KAAK,CAAC,GAAG,CAAC;iBACV,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAGa,AAAP,MAAM,CAAC,QAAQ,CAAC,GAAe,EAAE,IAAY;QAClD,MAAM,KAAK,GAAkB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7C,IAAI,OAAO,GAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QAEnD,KAAK,IAAI,CAAC,GAAW,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAuB,KAAK,CAAC,CAAC,CAAC,CAAC;YAEzC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACT,OAAO,SAAS,CAAC;YACnB,CAAC;YACD,MAAM,gBAAgB,GAAW,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAClD,MAAM,iBAAiB,GAAW,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAEnD,IAAI,gBAAgB,KAAK,CAAC,CAAC,IAAI,iBAAiB,KAAK,CAAC,CAAC,EAAE,CAAC;gBACxD,MAAM,QAAQ,GAAW,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;gBACxD,MAAM,WAAW,GAAW,GAAG,CAAC,KAAK,CACnC,gBAAgB,GAAG,CAAC,EACpB,iBAAiB,CAClB,CAAC;gBACF,IAAI,KAAK,GAAW,CAAC,CAAC;gBAEtB,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;oBAC3B,KAAK,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACN;;;;;;uBAMG;oBACH,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;wBACtC,OAAO,SAAS,CAAC;oBACnB,CAAC;oBAED,KAAK,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;gBACvC,CAAC;gBAED,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjE,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,CAAC;gBACrC,CAAC;qBAAM,CAAC;oBACN,OAAO,SAAS,CAAC;gBACnB,CAAC;YACH,CAAC;iBAAM,IAAI,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;gBACjD,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YACzB,CAAC;iBAAM,CAAC;gBACN,OAAO,SAAS,CAAC;YACnB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF;AA9ZqB;IADnB,WAAW,EAAE;;;;oCASb;AAGa;IADb,WAAW,EAAE;;;;uCAiHb;AAkBa;IADb,WAAW,EAAE;;;;mCA+Hb;AAQc;IADd,WAAW,EAAE;;;;wCAiDb;AAGa;IADb,WAAW,EAAE;;;;yCAkCb;AAGa;IADb,WAAW,EAAE;;;;4BAoDb"}
|