@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,268 @@
|
|
|
1
|
+
import { ModelSchema } from "../../../Utils/Schema/ModelSchema";
|
|
2
|
+
import Zod from "../../../Utils/Schema/Zod";
|
|
3
|
+
import {
|
|
4
|
+
getTableColumns,
|
|
5
|
+
TableColumnMetadata,
|
|
6
|
+
} from "../../../Types/Database/TableColumn";
|
|
7
|
+
import TableColumnType from "../../../Types/Database/TableColumnType";
|
|
8
|
+
import Dictionary from "../../../Types/Dictionary";
|
|
9
|
+
import DatabaseBaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
|
|
10
|
+
import Label from "../../../Models/DatabaseModels/Label";
|
|
11
|
+
import ApiKey from "../../../Models/DatabaseModels/ApiKey";
|
|
12
|
+
import Team from "../../../Models/DatabaseModels/Team";
|
|
13
|
+
import ShortLink from "../../../Models/DatabaseModels/ShortLink";
|
|
14
|
+
import MonitorGroup from "../../../Models/DatabaseModels/MonitorGroup";
|
|
15
|
+
import StatusPage from "../../../Models/DatabaseModels/StatusPage";
|
|
16
|
+
import Incident from "../../../Models/DatabaseModels/Incident";
|
|
17
|
+
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
18
|
+
|
|
19
|
+
/*
|
|
20
|
+
* Unit tests for ModelSchema — the Zod schema generator behind the public API
|
|
21
|
+
* (OpenAPI spec, request validation, and the Terraform provider generator) for
|
|
22
|
+
* every Postgres-backed database model.
|
|
23
|
+
*
|
|
24
|
+
* The generator is pure: it reads TypeORM column metadata and per-column
|
|
25
|
+
* access control off a freshly instantiated model, so no database connection is
|
|
26
|
+
* needed. These tests pin down the create/update/delete/select/sort/group-by
|
|
27
|
+
* contracts that API consumers depend on.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
type ModelCtor = new () => DatabaseBaseModel;
|
|
31
|
+
|
|
32
|
+
// A curated set of small, stable models spanning different column shapes.
|
|
33
|
+
const SAMPLE_MODELS: Array<ModelCtor> = [
|
|
34
|
+
Label,
|
|
35
|
+
ApiKey,
|
|
36
|
+
Team,
|
|
37
|
+
ShortLink,
|
|
38
|
+
MonitorGroup,
|
|
39
|
+
StatusPage,
|
|
40
|
+
Incident,
|
|
41
|
+
];
|
|
42
|
+
|
|
43
|
+
// Column types ModelSchema.getSortableTypes() considers sortable.
|
|
44
|
+
const SORTABLE_TYPES: Array<TableColumnType> = [
|
|
45
|
+
TableColumnType.VeryLongText,
|
|
46
|
+
TableColumnType.Slug,
|
|
47
|
+
TableColumnType.ShortText,
|
|
48
|
+
TableColumnType.LongText,
|
|
49
|
+
TableColumnType.Number,
|
|
50
|
+
TableColumnType.Date,
|
|
51
|
+
TableColumnType.Boolean,
|
|
52
|
+
TableColumnType.Description,
|
|
53
|
+
TableColumnType.ObjectID,
|
|
54
|
+
];
|
|
55
|
+
|
|
56
|
+
const CREATE_EXCLUDED_FIELDS: Array<string> = [
|
|
57
|
+
"_id",
|
|
58
|
+
"createdAt",
|
|
59
|
+
"updatedAt",
|
|
60
|
+
"deletedAt",
|
|
61
|
+
"version",
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const UPDATE_EXCLUDED_FIELDS: Array<string> = [
|
|
65
|
+
"createdAt",
|
|
66
|
+
"updatedAt",
|
|
67
|
+
"deletedAt",
|
|
68
|
+
"version",
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
const isZodObject: (schema: unknown) => boolean = (
|
|
72
|
+
schema: unknown,
|
|
73
|
+
): boolean => {
|
|
74
|
+
return schema instanceof Zod.ZodObject;
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
const shapeKeys: (schema: any) => Array<string> = (
|
|
78
|
+
schema: any,
|
|
79
|
+
): Array<string> => {
|
|
80
|
+
return Object.keys(schema.shape);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
describe("ModelSchema (Postgres)", () => {
|
|
84
|
+
describe("getModelSchema / getReadModelSchema", () => {
|
|
85
|
+
test("returns a non-empty ZodObject for a real model", () => {
|
|
86
|
+
const schema: any = ModelSchema.getModelSchema({ modelType: Label });
|
|
87
|
+
|
|
88
|
+
expect(isZodObject(schema)).toBe(true);
|
|
89
|
+
expect(shapeKeys(schema).length).toBeGreaterThan(0);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
test("excludes Entity (relation) columns from the schema", () => {
|
|
93
|
+
const model: Label = new Label();
|
|
94
|
+
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
95
|
+
const schema: any = ModelSchema.getModelSchema({ modelType: Label });
|
|
96
|
+
const keys: Array<string> = shapeKeys(schema);
|
|
97
|
+
|
|
98
|
+
for (const key in columns) {
|
|
99
|
+
const column: TableColumnMetadata | undefined = columns[key];
|
|
100
|
+
if (column && column.type === TableColumnType.Entity) {
|
|
101
|
+
expect(keys).not.toContain(key);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test("only includes columns that grant read access", () => {
|
|
107
|
+
const model: Label = new Label();
|
|
108
|
+
const accessControl: any = model.getColumnAccessControlForAllColumns();
|
|
109
|
+
const schema: any = ModelSchema.getModelSchema({ modelType: Label });
|
|
110
|
+
|
|
111
|
+
for (const key of shapeKeys(schema)) {
|
|
112
|
+
const control: any = accessControl[key];
|
|
113
|
+
/*
|
|
114
|
+
* Columns with declared access control must expose read permissions;
|
|
115
|
+
* columns without any declared control are allowed through.
|
|
116
|
+
*/
|
|
117
|
+
if (control) {
|
|
118
|
+
expect(control.read.length).toBeGreaterThan(0);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
test("builds read schemas for every sample model", () => {
|
|
124
|
+
for (const modelType of SAMPLE_MODELS) {
|
|
125
|
+
expect(isZodObject(ModelSchema.getModelSchema({ modelType }))).toBe(
|
|
126
|
+
true,
|
|
127
|
+
);
|
|
128
|
+
expect(isZodObject(ModelSchema.getReadModelSchema({ modelType }))).toBe(
|
|
129
|
+
true,
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
describe("getCreateModelSchema", () => {
|
|
136
|
+
test("excludes auto-generated system fields", () => {
|
|
137
|
+
for (const modelType of SAMPLE_MODELS) {
|
|
138
|
+
const schema: any = ModelSchema.getCreateModelSchema({ modelType });
|
|
139
|
+
const keys: Array<string> = shapeKeys(schema);
|
|
140
|
+
for (const excluded of CREATE_EXCLUDED_FIELDS) {
|
|
141
|
+
expect(keys).not.toContain(excluded);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("produces the same fields with and without OpenAPI metadata", () => {
|
|
147
|
+
const withOpenApi: any = ModelSchema.getCreateModelSchema({
|
|
148
|
+
modelType: Label,
|
|
149
|
+
});
|
|
150
|
+
const withoutOpenApi: any = ModelSchema.getCreateModelSchema({
|
|
151
|
+
modelType: Label,
|
|
152
|
+
disableOpenApiSchema: true,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
expect(isZodObject(withoutOpenApi)).toBe(true);
|
|
156
|
+
expect(shapeKeys(withoutOpenApi).sort()).toEqual(
|
|
157
|
+
shapeKeys(withOpenApi).sort(),
|
|
158
|
+
);
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
describe("getUpdateModelSchema", () => {
|
|
163
|
+
test("excludes immutable audit fields but keeps _id", () => {
|
|
164
|
+
const schema: any = ModelSchema.getUpdateModelSchema({
|
|
165
|
+
modelType: Label,
|
|
166
|
+
});
|
|
167
|
+
const keys: Array<string> = shapeKeys(schema);
|
|
168
|
+
|
|
169
|
+
for (const excluded of UPDATE_EXCLUDED_FIELDS) {
|
|
170
|
+
expect(keys).not.toContain(excluded);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
test("treats every field as optional (empty patch is valid)", () => {
|
|
175
|
+
for (const modelType of SAMPLE_MODELS) {
|
|
176
|
+
const schema: any = ModelSchema.getUpdateModelSchema({ modelType });
|
|
177
|
+
expect(schema.safeParse({}).success).toBe(true);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
describe("getDeleteModelSchema", () => {
|
|
183
|
+
test("only exposes the identifier field", () => {
|
|
184
|
+
for (const modelType of SAMPLE_MODELS) {
|
|
185
|
+
const schema: any = ModelSchema.getDeleteModelSchema({ modelType });
|
|
186
|
+
expect(shapeKeys(schema)).toEqual(["_id"]);
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe("getSelectModelSchema", () => {
|
|
192
|
+
test("marks fields as optional booleans and rejects other types", () => {
|
|
193
|
+
const schema: any = ModelSchema.getSelectModelSchema({
|
|
194
|
+
modelType: Label,
|
|
195
|
+
});
|
|
196
|
+
const keys: Array<string> = shapeKeys(schema);
|
|
197
|
+
const someKey: string = keys[0]!;
|
|
198
|
+
|
|
199
|
+
expect(keys.length).toBeGreaterThan(0);
|
|
200
|
+
expect(schema.safeParse({}).success).toBe(true);
|
|
201
|
+
expect(schema.safeParse({ [someKey]: true }).success).toBe(true);
|
|
202
|
+
expect(schema.safeParse({ [someKey]: "select-me" }).success).toBe(false);
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("builds a select schema for every sample model", () => {
|
|
206
|
+
for (const modelType of SAMPLE_MODELS) {
|
|
207
|
+
expect(
|
|
208
|
+
isZodObject(ModelSchema.getSelectModelSchema({ modelType })),
|
|
209
|
+
).toBe(true);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
describe("getSortModelSchema", () => {
|
|
215
|
+
test("includes only sortable column types", () => {
|
|
216
|
+
const model: Label = new Label();
|
|
217
|
+
const columns: Dictionary<TableColumnMetadata> = getTableColumns(model);
|
|
218
|
+
const schema: any = ModelSchema.getSortModelSchema({ modelType: Label });
|
|
219
|
+
const keys: Array<string> = shapeKeys(schema);
|
|
220
|
+
|
|
221
|
+
for (const key in columns) {
|
|
222
|
+
const column: TableColumnMetadata | undefined = columns[key];
|
|
223
|
+
if (!column) {
|
|
224
|
+
continue;
|
|
225
|
+
}
|
|
226
|
+
if (SORTABLE_TYPES.includes(column.type)) {
|
|
227
|
+
expect(keys).toContain(key);
|
|
228
|
+
} else {
|
|
229
|
+
expect(keys).not.toContain(key);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
test("accepts only ASC/DESC values", () => {
|
|
235
|
+
const schema: any = ModelSchema.getSortModelSchema({ modelType: Label });
|
|
236
|
+
const key: string = shapeKeys(schema)[0]!;
|
|
237
|
+
|
|
238
|
+
expect(schema.safeParse({}).success).toBe(true);
|
|
239
|
+
expect(schema.safeParse({ [key]: SortOrder.Ascending }).success).toBe(
|
|
240
|
+
true,
|
|
241
|
+
);
|
|
242
|
+
expect(schema.safeParse({ [key]: SortOrder.Descending }).success).toBe(
|
|
243
|
+
true,
|
|
244
|
+
);
|
|
245
|
+
expect(schema.safeParse({ [key]: "RANDOM" }).success).toBe(false);
|
|
246
|
+
});
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
describe("getGroupByModelSchema", () => {
|
|
250
|
+
test("builds a group-by schema and accepts an empty object", () => {
|
|
251
|
+
for (const modelType of SAMPLE_MODELS) {
|
|
252
|
+
const schema: any = ModelSchema.getGroupByModelSchema({ modelType });
|
|
253
|
+
expect(isZodObject(schema)).toBe(true);
|
|
254
|
+
expect(schema.safeParse({}).success).toBe(true);
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
describe("getQueryModelSchema", () => {
|
|
260
|
+
test("builds a query schema that accepts an empty query", () => {
|
|
261
|
+
for (const modelType of SAMPLE_MODELS) {
|
|
262
|
+
const schema: any = ModelSchema.getQueryModelSchema({ modelType });
|
|
263
|
+
expect(isZodObject(schema)).toBe(true);
|
|
264
|
+
expect(schema.safeParse({}).success).toBe(true);
|
|
265
|
+
}
|
|
266
|
+
});
|
|
267
|
+
});
|
|
268
|
+
});
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import {
|
|
2
|
+
computeEntityKey,
|
|
3
|
+
INVENTORY_ENTITY_IDENTITY_ATTRIBUTE,
|
|
4
|
+
keyForInventoryEntity,
|
|
5
|
+
keyForManualEntity,
|
|
6
|
+
MANUAL_ENTITY_IDENTITY_ATTRIBUTE,
|
|
7
|
+
} from "../../../Utils/Telemetry/EntityKey";
|
|
8
|
+
import EntityType from "../../../Types/Telemetry/EntityType";
|
|
9
|
+
import { describe, expect, test } from "@jest/globals";
|
|
10
|
+
|
|
11
|
+
/*
|
|
12
|
+
* Identity for the two entity flavours that never pass through ingest:
|
|
13
|
+
* manually registered CIs and rows mirrored from OneUptime's inventory
|
|
14
|
+
* tables. Neither has an ingest-side resolver to byte-match, so the only
|
|
15
|
+
* things that must hold are the ones tested here — determinism, tenant and
|
|
16
|
+
* type separation, and the specific choice of what each keys on (a manual CI
|
|
17
|
+
* on its name, an inventory mirror on its owning row's id).
|
|
18
|
+
*
|
|
19
|
+
* The consequence of getting these wrong is duplicate registry rows that
|
|
20
|
+
* both look correct, so each property is pinned rather than assumed.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const PROJECT: string = "proj1";
|
|
24
|
+
const OTHER_PROJECT: string = "proj2";
|
|
25
|
+
const RESOURCE_ID: string = "6f2e5c1a-0b3d-4e5f-8a9b-1c2d3e4f5a6b";
|
|
26
|
+
|
|
27
|
+
describe("keyForManualEntity", () => {
|
|
28
|
+
test("is deterministic", () => {
|
|
29
|
+
expect(
|
|
30
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, "Stripe API"),
|
|
31
|
+
).toBe(
|
|
32
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, "Stripe API"),
|
|
33
|
+
);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("is a 16-char lowercase hex key, like every other entity key", () => {
|
|
37
|
+
const key: string = keyForManualEntity(
|
|
38
|
+
PROJECT,
|
|
39
|
+
EntityType.ExternalService,
|
|
40
|
+
"Stripe API",
|
|
41
|
+
);
|
|
42
|
+
expect(key).toMatch(/^[0-9a-f]{16}$/);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("canonicalizes the name, so casing and padding do not fork identity", () => {
|
|
46
|
+
const canonical: string = keyForManualEntity(
|
|
47
|
+
PROJECT,
|
|
48
|
+
EntityType.ExternalService,
|
|
49
|
+
"Stripe API",
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
expect(
|
|
53
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, " stripe api "),
|
|
54
|
+
).toBe(canonical);
|
|
55
|
+
expect(
|
|
56
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, "STRIPE API"),
|
|
57
|
+
).toBe(canonical);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test("separates tenants", () => {
|
|
61
|
+
expect(
|
|
62
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, "Stripe API"),
|
|
63
|
+
).not.toBe(
|
|
64
|
+
keyForManualEntity(
|
|
65
|
+
OTHER_PROJECT,
|
|
66
|
+
EntityType.ExternalService,
|
|
67
|
+
"Stripe API",
|
|
68
|
+
),
|
|
69
|
+
);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test("separates types, so one name can exist as two kinds of thing", () => {
|
|
73
|
+
expect(
|
|
74
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, "payments"),
|
|
75
|
+
).not.toBe(
|
|
76
|
+
keyForManualEntity(PROJECT, EntityType.ExternalDatabase, "payments"),
|
|
77
|
+
);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("distinct names within a type get distinct keys", () => {
|
|
81
|
+
expect(
|
|
82
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, "Stripe API"),
|
|
83
|
+
).not.toBe(
|
|
84
|
+
keyForManualEntity(PROJECT, EntityType.ExternalService, "Adyen API"),
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test("matches computeEntityKey over the documented identity attribute", () => {
|
|
89
|
+
expect(
|
|
90
|
+
keyForManualEntity(PROJECT, EntityType.Appliance, "Rack PDU 3"),
|
|
91
|
+
).toBe(
|
|
92
|
+
computeEntityKey({
|
|
93
|
+
projectId: PROJECT,
|
|
94
|
+
entityType: EntityType.Appliance,
|
|
95
|
+
identifyingAttributes: {
|
|
96
|
+
[MANUAL_ENTITY_IDENTITY_ATTRIBUTE]: "rack pdu 3",
|
|
97
|
+
},
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
describe("keyForInventoryEntity", () => {
|
|
104
|
+
test("is deterministic", () => {
|
|
105
|
+
expect(
|
|
106
|
+
keyForInventoryEntity(PROJECT, EntityType.NetworkDevice, RESOURCE_ID),
|
|
107
|
+
).toBe(
|
|
108
|
+
keyForInventoryEntity(PROJECT, EntityType.NetworkDevice, RESOURCE_ID),
|
|
109
|
+
);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
test("keys on the owning row id, so renaming the row keeps its identity", () => {
|
|
113
|
+
/*
|
|
114
|
+
* This is the whole reason inventory mirrors key on the id rather than
|
|
115
|
+
* the name: a rename must update the existing registry row, not orphan
|
|
116
|
+
* it and mint a second one alongside.
|
|
117
|
+
*/
|
|
118
|
+
const key: string = keyForInventoryEntity(
|
|
119
|
+
PROJECT,
|
|
120
|
+
EntityType.NetworkDevice,
|
|
121
|
+
RESOURCE_ID,
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
expect(
|
|
125
|
+
keyForInventoryEntity(PROJECT, EntityType.NetworkDevice, RESOURCE_ID),
|
|
126
|
+
).toBe(key);
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test("separates tenants and types", () => {
|
|
130
|
+
const key: string = keyForInventoryEntity(
|
|
131
|
+
PROJECT,
|
|
132
|
+
EntityType.NetworkDevice,
|
|
133
|
+
RESOURCE_ID,
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
expect(
|
|
137
|
+
keyForInventoryEntity(
|
|
138
|
+
OTHER_PROJECT,
|
|
139
|
+
EntityType.NetworkDevice,
|
|
140
|
+
RESOURCE_ID,
|
|
141
|
+
),
|
|
142
|
+
).not.toBe(key);
|
|
143
|
+
expect(
|
|
144
|
+
keyForInventoryEntity(PROJECT, EntityType.IoTDevice, RESOURCE_ID),
|
|
145
|
+
).not.toBe(key);
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
test("distinct rows get distinct keys", () => {
|
|
149
|
+
expect(
|
|
150
|
+
keyForInventoryEntity(PROJECT, EntityType.NetworkDevice, RESOURCE_ID),
|
|
151
|
+
).not.toBe(
|
|
152
|
+
keyForInventoryEntity(
|
|
153
|
+
PROJECT,
|
|
154
|
+
EntityType.NetworkDevice,
|
|
155
|
+
"11111111-2222-3333-4444-555555555555",
|
|
156
|
+
),
|
|
157
|
+
);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("matches computeEntityKey over the documented identity attribute", () => {
|
|
161
|
+
expect(
|
|
162
|
+
keyForInventoryEntity(PROJECT, EntityType.CloudResource, RESOURCE_ID),
|
|
163
|
+
).toBe(
|
|
164
|
+
computeEntityKey({
|
|
165
|
+
projectId: PROJECT,
|
|
166
|
+
entityType: EntityType.CloudResource,
|
|
167
|
+
identifyingAttributes: {
|
|
168
|
+
[INVENTORY_ENTITY_IDENTITY_ATTRIBUTE]: RESOURCE_ID,
|
|
169
|
+
},
|
|
170
|
+
}),
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe("manual and inventory identities do not collide", () => {
|
|
176
|
+
test("the two attributes are distinct", () => {
|
|
177
|
+
expect(MANUAL_ENTITY_IDENTITY_ATTRIBUTE).not.toBe(
|
|
178
|
+
INVENTORY_ENTITY_IDENTITY_ATTRIBUTE,
|
|
179
|
+
);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test("same project, same type, same literal value still key differently", () => {
|
|
183
|
+
/*
|
|
184
|
+
* A manual CI literally named after a resource id would otherwise
|
|
185
|
+
* collide with the mirror of that resource.
|
|
186
|
+
*/
|
|
187
|
+
expect(
|
|
188
|
+
keyForManualEntity(PROJECT, EntityType.Appliance, RESOURCE_ID),
|
|
189
|
+
).not.toBe(
|
|
190
|
+
keyForInventoryEntity(PROJECT, EntityType.Appliance, RESOURCE_ID),
|
|
191
|
+
);
|
|
192
|
+
});
|
|
193
|
+
});
|
|
@@ -26,6 +26,31 @@ export type NetworkTopologyLinkProtocol = "lldp" | "cdp" | "fdb";
|
|
|
26
26
|
*/
|
|
27
27
|
export type NetworkTopologyNodeKind = "device" | "unmanaged" | "endpoint";
|
|
28
28
|
|
|
29
|
+
/*
|
|
30
|
+
* What the node DOES on the network, as opposed to what we know about it
|
|
31
|
+
* (`kind`). Derived server-side from the identity SNMP and the discovery
|
|
32
|
+
* protocols already report — sysObjectId, sysDescr, model/platform, and
|
|
33
|
+
* finally the hostname — because a map on which a router, a switch and a
|
|
34
|
+
* camera are the same circle cannot be read at a glance.
|
|
35
|
+
*
|
|
36
|
+
* "unknown" is a real answer, not a failure: guessing a role from thin
|
|
37
|
+
* evidence is worse than drawing a neutral node, so the classifier only
|
|
38
|
+
* commits when the evidence names a product family or says the word.
|
|
39
|
+
*/
|
|
40
|
+
export type NetworkTopologyDeviceRole =
|
|
41
|
+
| "router"
|
|
42
|
+
| "switch"
|
|
43
|
+
| "firewall"
|
|
44
|
+
| "wirelessAccessPoint"
|
|
45
|
+
| "loadBalancer"
|
|
46
|
+
| "server"
|
|
47
|
+
| "storage"
|
|
48
|
+
| "printer"
|
|
49
|
+
| "camera"
|
|
50
|
+
| "phone"
|
|
51
|
+
| "host"
|
|
52
|
+
| "unknown";
|
|
53
|
+
|
|
29
54
|
export interface NetworkTopologyNode {
|
|
30
55
|
// Device id for managed nodes; a synthetic "unmanaged:<key>" id otherwise.
|
|
31
56
|
id: string;
|
|
@@ -34,6 +59,12 @@ export interface NetworkTopologyNode {
|
|
|
34
59
|
status: NetworkTopologyNodeStatus;
|
|
35
60
|
// Missing on older payloads — derive from isManaged.
|
|
36
61
|
kind?: NetworkTopologyNodeKind | undefined;
|
|
62
|
+
/*
|
|
63
|
+
* What the node does on the network (router, switch, firewall, ...).
|
|
64
|
+
* Missing on older payloads, and "unknown" when the evidence did not
|
|
65
|
+
* name one — readers must treat both the same way.
|
|
66
|
+
*/
|
|
67
|
+
role?: NetworkTopologyDeviceRole | undefined;
|
|
37
68
|
interfacesUp?: number | undefined;
|
|
38
69
|
interfacesDown?: number | undefined;
|
|
39
70
|
// Extra device identity for search and the detail panel (managed nodes).
|
|
@@ -40,46 +40,140 @@ import Phone from "./Phone";
|
|
|
40
40
|
import Port from "./Port";
|
|
41
41
|
import Version from "./Version";
|
|
42
42
|
|
|
43
|
+
/*
|
|
44
|
+
* Every entry is a getter, not a direct reference.
|
|
45
|
+
*
|
|
46
|
+
* Three of these classes — Includes, IncludesAll and IncludesNone — import
|
|
47
|
+
* JSONFunctions so their fromJSON can deserialize the values inside them, and
|
|
48
|
+
* JSONFunctions imports this dictionary. That is a cycle, and with a plain
|
|
49
|
+
* object literal the entry a cycle passes through is captured as `undefined`:
|
|
50
|
+
* whichever of the two modules loads second sees the first only half
|
|
51
|
+
* initialized. Which of them loads first depends on the whole app's import
|
|
52
|
+
* graph, so `{"_type":"Includes","value":[...]}` deserialized into a real
|
|
53
|
+
* Includes in some entry points and stayed a plain object in others — and a
|
|
54
|
+
* plain object reaching TypeORM is a silently wrong query, not an error.
|
|
55
|
+
*
|
|
56
|
+
* A getter defers the lookup to the first property access, by which time every
|
|
57
|
+
* module has finished initializing.
|
|
58
|
+
*/
|
|
43
59
|
const SerializableObjectDictionary: Dictionary<any> = {
|
|
44
|
-
[ObjectType.Phone]:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
[ObjectType.
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
[ObjectType.
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
[ObjectType.
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
[ObjectType.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
[ObjectType.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
[ObjectType.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
[ObjectType.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
[ObjectType.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
[ObjectType.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
[ObjectType.
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
[ObjectType.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
[ObjectType.
|
|
81
|
-
|
|
82
|
-
|
|
60
|
+
get [ObjectType.Phone](): any {
|
|
61
|
+
return Phone;
|
|
62
|
+
},
|
|
63
|
+
get [ObjectType.DateTime](): any {
|
|
64
|
+
return OneUptimeDate;
|
|
65
|
+
},
|
|
66
|
+
get [ObjectType.ObjectID](): any {
|
|
67
|
+
return ObjectID;
|
|
68
|
+
},
|
|
69
|
+
get [ObjectType.Name](): any {
|
|
70
|
+
return Name;
|
|
71
|
+
},
|
|
72
|
+
get [ObjectType.EqualTo](): any {
|
|
73
|
+
return EqualTo;
|
|
74
|
+
},
|
|
75
|
+
get [ObjectType.EqualToOrNull](): any {
|
|
76
|
+
return EqualToOrNull;
|
|
77
|
+
},
|
|
78
|
+
get [ObjectType.MonitorSteps](): any {
|
|
79
|
+
return MonitorSteps;
|
|
80
|
+
},
|
|
81
|
+
get [ObjectType.MonitorStep](): any {
|
|
82
|
+
return MonitorStep;
|
|
83
|
+
},
|
|
84
|
+
get [ObjectType.MonitorCriteria](): any {
|
|
85
|
+
return MonitorCriteria;
|
|
86
|
+
},
|
|
87
|
+
get [ObjectType.MonitorCriteriaInstance](): any {
|
|
88
|
+
return MonitorCriteriaInstance;
|
|
89
|
+
},
|
|
90
|
+
get [ObjectType.NotEqual](): any {
|
|
91
|
+
return NotEqual;
|
|
92
|
+
},
|
|
93
|
+
get [ObjectType.Email](): any {
|
|
94
|
+
return Email;
|
|
95
|
+
},
|
|
96
|
+
get [ObjectType.Color](): any {
|
|
97
|
+
return Color;
|
|
98
|
+
},
|
|
99
|
+
get [ObjectType.Domain](): any {
|
|
100
|
+
return Domain;
|
|
101
|
+
},
|
|
102
|
+
get [ObjectType.Version](): any {
|
|
103
|
+
return Version;
|
|
104
|
+
},
|
|
105
|
+
get [ObjectType.Route](): any {
|
|
106
|
+
return Route;
|
|
107
|
+
},
|
|
108
|
+
get [ObjectType.URL](): any {
|
|
109
|
+
return URL;
|
|
110
|
+
},
|
|
111
|
+
get [ObjectType.IP](): any {
|
|
112
|
+
return IP;
|
|
113
|
+
},
|
|
114
|
+
get [ObjectType.Search](): any {
|
|
115
|
+
return Search;
|
|
116
|
+
},
|
|
117
|
+
get [ObjectType.MultiSearch](): any {
|
|
118
|
+
return MultiSearch;
|
|
119
|
+
},
|
|
120
|
+
get [ObjectType.GreaterThan](): any {
|
|
121
|
+
return GreaterThan;
|
|
122
|
+
},
|
|
123
|
+
get [ObjectType.GreaterThanOrEqual](): any {
|
|
124
|
+
return GreaterThanOrEqual;
|
|
125
|
+
},
|
|
126
|
+
get [ObjectType.LessThan](): any {
|
|
127
|
+
return LessThan;
|
|
128
|
+
},
|
|
129
|
+
get [ObjectType.LessThanOrEqual](): any {
|
|
130
|
+
return LessThanOrEqual;
|
|
131
|
+
},
|
|
132
|
+
get [ObjectType.LessThanOrNull](): any {
|
|
133
|
+
return LessThanOrNull;
|
|
134
|
+
},
|
|
135
|
+
get [ObjectType.GreaterThanOrNull](): any {
|
|
136
|
+
return GreaterThanOrNull;
|
|
137
|
+
},
|
|
138
|
+
get [ObjectType.Port](): any {
|
|
139
|
+
return Port;
|
|
140
|
+
},
|
|
141
|
+
get [ObjectType.Hostname](): any {
|
|
142
|
+
return Hostname;
|
|
143
|
+
},
|
|
144
|
+
get [ObjectType.HashedString](): any {
|
|
145
|
+
return HashedString;
|
|
146
|
+
},
|
|
147
|
+
get [ObjectType.InBetween](): any {
|
|
148
|
+
return InBetween;
|
|
149
|
+
},
|
|
150
|
+
get [ObjectType.Includes](): any {
|
|
151
|
+
return Includes;
|
|
152
|
+
},
|
|
153
|
+
get [ObjectType.IncludesAll](): any {
|
|
154
|
+
return IncludesAll;
|
|
155
|
+
},
|
|
156
|
+
get [ObjectType.IncludesNone](): any {
|
|
157
|
+
return IncludesNone;
|
|
158
|
+
},
|
|
159
|
+
get [ObjectType.StartsWith](): any {
|
|
160
|
+
return StartsWith;
|
|
161
|
+
},
|
|
162
|
+
get [ObjectType.EndsWith](): any {
|
|
163
|
+
return EndsWith;
|
|
164
|
+
},
|
|
165
|
+
get [ObjectType.NotContains](): any {
|
|
166
|
+
return NotContains;
|
|
167
|
+
},
|
|
168
|
+
get [ObjectType.NotNull](): any {
|
|
169
|
+
return NotNull;
|
|
170
|
+
},
|
|
171
|
+
get [ObjectType.IsNull](): any {
|
|
172
|
+
return IsNull;
|
|
173
|
+
},
|
|
174
|
+
get [ObjectType.Recurring](): any {
|
|
175
|
+
return Recurring;
|
|
176
|
+
},
|
|
83
177
|
};
|
|
84
178
|
|
|
85
179
|
export default SerializableObjectDictionary;
|