@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.
Files changed (186) hide show
  1. package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
  2. package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
  3. package/Models/DatabaseModels/WorkflowLog.ts +38 -0
  4. package/Server/API/UserAPI.ts +16 -1
  5. package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
  7. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  8. package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
  9. package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
  10. package/Server/Services/TelemetryEntityService.ts +114 -1
  11. package/Server/Types/Workflow/Components/API/Utils.ts +44 -1
  12. package/Server/Types/Workflow/TriggerCode.ts +12 -0
  13. package/Server/Types/Workflow/Workflow.ts +5 -0
  14. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
  15. package/Server/Utils/VM/VMAPI.ts +56 -8
  16. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
  17. package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
  18. package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
  19. package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
  20. package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
  21. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
  22. package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
  23. package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
  24. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
  25. package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
  26. package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
  27. package/Tests/Types/Workflow/Templates.test.ts +403 -0
  28. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
  29. package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
  30. package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
  31. package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
  32. package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
  33. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +42 -0
  34. package/Tests/UI/Components/ModalPortalDismissal.test.tsx +90 -0
  35. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +49 -7
  36. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
  37. package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
  38. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
  39. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
  40. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
  41. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
  42. package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
  43. package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
  44. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
  45. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
  46. package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
  47. package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
  48. package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
  49. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
  50. package/Types/SerializableObjectDictionary.ts +133 -39
  51. package/Types/Telemetry/EntitySource.ts +40 -0
  52. package/Types/Telemetry/EntityType.ts +27 -0
  53. package/Types/Telemetry/EntityTypeGroups.ts +65 -0
  54. package/Types/Workflow/Component.ts +29 -0
  55. package/Types/Workflow/Components/API.ts +35 -0
  56. package/Types/Workflow/Components/BaseModel.ts +7 -3
  57. package/Types/Workflow/StepTrace.ts +181 -0
  58. package/Types/Workflow/TemplateSyntax.ts +499 -0
  59. package/Types/Workflow/Templates.ts +316 -0
  60. package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
  61. package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
  62. package/UI/Components/Dictionary/Dictionary.tsx +23 -6
  63. package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
  64. package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
  65. package/UI/Components/Forms/Types/Field.ts +7 -0
  66. package/UI/Components/Forms/Validation.ts +63 -1
  67. package/UI/Components/Input/Input.tsx +31 -3
  68. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
  69. package/UI/Components/Modal/Modal.tsx +37 -4
  70. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
  71. package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
  72. package/UI/Components/Workflow/Component.tsx +28 -26
  73. package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
  74. package/UI/Components/Workflow/GraphLint.ts +591 -0
  75. package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
  76. package/UI/Components/Workflow/ModelSchema.ts +196 -0
  77. package/UI/Components/Workflow/RunForm.tsx +41 -7
  78. package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
  79. package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
  80. package/UI/Components/Workflow/Utils.ts +93 -1
  81. package/UI/Components/Workflow/Workflow.tsx +77 -4
  82. package/UI/Types/LayeredDismissal.ts +31 -0
  83. package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
  84. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
  85. package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
  86. package/Utils/Telemetry/EntityKey.ts +66 -0
  87. package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
  88. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
  89. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
  90. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
  91. package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
  92. package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
  93. package/build/dist/Server/API/UserAPI.js +16 -1
  94. package/build/dist/Server/API/UserAPI.js.map +1 -1
  95. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
  96. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
  97. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
  98. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
  99. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  100. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  101. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
  102. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  103. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
  104. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  105. package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
  106. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  107. package/build/dist/Server/Types/Workflow/Components/API/Utils.js +28 -0
  108. package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
  109. package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
  110. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
  111. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
  112. package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
  113. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  114. package/build/dist/Types/SerializableObjectDictionary.js +133 -39
  115. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  116. package/build/dist/Types/Telemetry/EntitySource.js +39 -0
  117. package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
  118. package/build/dist/Types/Telemetry/EntityType.js +27 -0
  119. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  120. package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
  121. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
  122. package/build/dist/Types/Workflow/Component.js +21 -0
  123. package/build/dist/Types/Workflow/Component.js.map +1 -1
  124. package/build/dist/Types/Workflow/Components/API.js +35 -0
  125. package/build/dist/Types/Workflow/Components/API.js.map +1 -1
  126. package/build/dist/Types/Workflow/Components/BaseModel.js +7 -3
  127. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  128. package/build/dist/Types/Workflow/StepTrace.js +104 -0
  129. package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
  130. package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
  131. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
  132. package/build/dist/Types/Workflow/Templates.js +218 -0
  133. package/build/dist/Types/Workflow/Templates.js.map +1 -0
  134. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
  135. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
  136. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
  137. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
  138. package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
  139. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  140. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
  141. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  142. package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
  143. package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
  144. package/build/dist/UI/Components/Forms/Validation.js +44 -0
  145. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  146. package/build/dist/UI/Components/Input/Input.js +12 -4
  147. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  148. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
  149. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  150. package/build/dist/UI/Components/Modal/Modal.js +31 -5
  151. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  152. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
  153. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  154. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
  155. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  156. package/build/dist/UI/Components/Workflow/Component.js +20 -19
  157. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  158. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
  159. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  160. package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
  161. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
  162. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
  163. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
  164. package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
  165. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
  166. package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
  167. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  168. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
  169. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
  170. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
  171. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
  172. package/build/dist/UI/Components/Workflow/Utils.js +73 -1
  173. package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
  174. package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
  175. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  176. package/build/dist/UI/Types/LayeredDismissal.js +21 -0
  177. package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
  178. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
  179. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  180. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
  181. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
  182. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
  183. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  184. package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
  185. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  186. package/package.json +1 -1
@@ -0,0 +1,396 @@
1
+ /*
2
+ * Static checks over a workflow graph, run in the builder as the user edits.
3
+ *
4
+ * Every rule here corresponds to a way the runner (App/FeatureSet/Workflow/
5
+ * Services/RunWorkflow.ts) either throws at run time or — worse — carries on
6
+ * quietly with the wrong value. The point is to move those failures from "3am,
7
+ * in a log blob, after the trigger already fired" to "in the editor, before
8
+ * you save".
9
+ *
10
+ * Rules only fire on things that are knowable from the graph alone. Anything
11
+ * needing a network round trip (does this workflow variable exist?) is checked
12
+ * for shape but not for existence, because a false positive here puts a red
13
+ * badge on a workflow that runs perfectly.
14
+ */
15
+ import { ComponentInputType, ComponentType, NodeType, isJSON5ToleratedInputType, } from "../../../Types/Workflow/Component";
16
+ import { ReferenceRootType, TemplateExpressionKind, checkJSONSyntax, looksLikeReferencePath, parseReferencePath, parseTemplateExpressions, } from "../../../Types/Workflow/TemplateSyntax";
17
+ export var WorkflowLintSeverity;
18
+ (function (WorkflowLintSeverity) {
19
+ /** The workflow will fail, or silently do the wrong thing, as written. */
20
+ WorkflowLintSeverity["Error"] = "Error";
21
+ /** Suspicious but survivable — e.g. a step that can never be reached. */
22
+ WorkflowLintSeverity["Warning"] = "Warning";
23
+ })(WorkflowLintSeverity || (WorkflowLintSeverity = {}));
24
+ export var WorkflowLintRule;
25
+ (function (WorkflowLintRule) {
26
+ WorkflowLintRule["MissingRequiredArgument"] = "MissingRequiredArgument";
27
+ WorkflowLintRule["InvalidJSON"] = "InvalidJSON";
28
+ WorkflowLintRule["ReferenceHasWhitespace"] = "ReferenceHasWhitespace";
29
+ WorkflowLintRule["UnknownReferenceRoot"] = "UnknownReferenceRoot";
30
+ WorkflowLintRule["UnknownReferencedComponent"] = "UnknownReferencedComponent";
31
+ WorkflowLintRule["UnknownReferencedReturnValue"] = "UnknownReferencedReturnValue";
32
+ WorkflowLintRule["SelfReference"] = "SelfReference";
33
+ WorkflowLintRule["ForwardReference"] = "ForwardReference";
34
+ WorkflowLintRule["ReferenceToUnreachableComponent"] = "ReferenceToUnreachableComponent";
35
+ WorkflowLintRule["DuplicateComponentId"] = "DuplicateComponentId";
36
+ WorkflowLintRule["ComponentIdContainsDot"] = "ComponentIdContainsDot";
37
+ WorkflowLintRule["UnreachableComponent"] = "UnreachableComponent";
38
+ WorkflowLintRule["NoTrigger"] = "NoTrigger";
39
+ })(WorkflowLintRule || (WorkflowLintRule = {}));
40
+ /*
41
+ * Argument types the builder stores as a JSON document in a code editor. A
42
+ * malformed one throws in RunWorkflow.getComponentArguments (for JSON / Query /
43
+ * Select) or in the component itself (JSONFunctions.parse in
44
+ * CreateOneBaseModel, ApiComponentUtils.sanitizeArgs, and friends), so all of
45
+ * them are worth checking up front.
46
+ */
47
+ const JSON_DOCUMENT_INPUT_TYPES = [
48
+ ComponentInputType.JSON,
49
+ ComponentInputType.JSONArray,
50
+ ComponentInputType.Query,
51
+ ComponentInputType.Select,
52
+ ComponentInputType.BaseModel,
53
+ ComponentInputType.BaseModelArray,
54
+ ComponentInputType.StringDictionary,
55
+ ];
56
+ /*
57
+ * `false` and `0` are values a builder deliberately set — only absence and the
58
+ * empty box count as missing. An empty object/array counts as missing too: the
59
+ * Dictionary editor writes `{}` for a field nobody filled in.
60
+ */
61
+ const isEmptyArgumentValue = (value) => {
62
+ if (value === undefined || value === null) {
63
+ return true;
64
+ }
65
+ if (typeof value === "string") {
66
+ return value.trim() === "";
67
+ }
68
+ if (Array.isArray(value)) {
69
+ return value.length === 0;
70
+ }
71
+ if (typeof value === "object") {
72
+ return Object.keys(value).length === 0;
73
+ }
74
+ return false;
75
+ };
76
+ const isRealNode = (node) => {
77
+ return Boolean(node.data &&
78
+ node.data.nodeType !== NodeType.PlaceholderNode &&
79
+ node.data.metadata);
80
+ };
81
+ /** Every node id reachable by following edges forward from `startNodeIds`. */
82
+ const buildReachableSet = (startNodeIds, adjacency) => {
83
+ const reachable = new Set();
84
+ const queue = [...startNodeIds];
85
+ while (queue.length > 0) {
86
+ const current = queue.shift();
87
+ if (reachable.has(current)) {
88
+ continue;
89
+ }
90
+ reachable.add(current);
91
+ for (const next of adjacency[current] || []) {
92
+ if (!reachable.has(next)) {
93
+ queue.push(next);
94
+ }
95
+ }
96
+ }
97
+ return reachable;
98
+ };
99
+ /*
100
+ * A reference can hide anywhere a string can: the Dictionary editor stores an
101
+ * object whose values are strings, and imported graphs can hold arrays. Walk
102
+ * the whole value so {{...}} inside a header value is linted too.
103
+ */
104
+ const collectArgumentStrings = (value) => {
105
+ if (typeof value === "string") {
106
+ return [value];
107
+ }
108
+ if (Array.isArray(value)) {
109
+ return value.flatMap((item) => {
110
+ return collectArgumentStrings(item);
111
+ });
112
+ }
113
+ if (value && typeof value === "object") {
114
+ return Object.values(value).flatMap((item) => {
115
+ return collectArgumentStrings(item);
116
+ });
117
+ }
118
+ return [];
119
+ };
120
+ /**
121
+ * Check a workflow graph and report everything wrong with it.
122
+ */
123
+ export const lintWorkflowGraph = (graph) => {
124
+ var _a;
125
+ const issues = [];
126
+ const nodes = (graph.nodes || []).filter(isRealNode);
127
+ const edges = graph.edges || [];
128
+ const addIssue = (issue) => {
129
+ issues.push(issue);
130
+ };
131
+ /* ---- indexes ---------------------------------------------------------- */
132
+ // The runner keys its storage map on node.data.id, not the react-flow id.
133
+ const nodesByComponentId = {};
134
+ const componentIdCounts = {};
135
+ for (const node of nodes) {
136
+ const componentId = node.data.id;
137
+ if (!componentId) {
138
+ continue;
139
+ }
140
+ componentIdCounts[componentId] = (componentIdCounts[componentId] || 0) + 1;
141
+ if (!nodesByComponentId[componentId]) {
142
+ nodesByComponentId[componentId] = node;
143
+ }
144
+ }
145
+ const adjacency = {};
146
+ for (const edge of edges) {
147
+ if (!adjacency[edge.source]) {
148
+ adjacency[edge.source] = [];
149
+ }
150
+ (_a = adjacency[edge.source]) === null || _a === void 0 ? void 0 : _a.push(edge.target);
151
+ }
152
+ const triggerNodes = nodes.filter((node) => {
153
+ return node.data.componentType === ComponentType.Trigger;
154
+ });
155
+ const reachableFromTrigger = buildReachableSet(triggerNodes.map((node) => {
156
+ return node.id;
157
+ }), adjacency);
158
+ /*
159
+ * Strict descendants of a node, computed at most once per node — the
160
+ * reference rules ask for this per argument, and recomputing a traversal
161
+ * inside that loop makes linting quadratic on graphs that are already wide.
162
+ */
163
+ const descendantCache = {};
164
+ const getDescendants = (nodeId) => {
165
+ let descendants = descendantCache[nodeId];
166
+ if (!descendants) {
167
+ descendants = buildReachableSet(adjacency[nodeId] || [], adjacency);
168
+ descendantCache[nodeId] = descendants;
169
+ }
170
+ return descendants;
171
+ };
172
+ /* ---- graph-wide rules -------------------------------------------------- */
173
+ if (nodes.length > 0 && triggerNodes.length === 0) {
174
+ addIssue({
175
+ rule: WorkflowLintRule.NoTrigger,
176
+ severity: WorkflowLintSeverity.Error,
177
+ nodeId: null,
178
+ componentId: null,
179
+ argumentId: null,
180
+ message: "This workflow has no trigger, so it can never start. Add a trigger and connect it to the first step.",
181
+ });
182
+ }
183
+ /* ---- per-node rules ---------------------------------------------------- */
184
+ for (const node of nodes) {
185
+ const data = node.data;
186
+ const componentId = data.id;
187
+ const argumentValues = data.arguments || {};
188
+ const addNodeIssue = (params) => {
189
+ addIssue({
190
+ rule: params.rule,
191
+ severity: params.severity,
192
+ nodeId: node.id,
193
+ componentId: componentId || null,
194
+ argumentId: params.argumentId || null,
195
+ message: params.message,
196
+ });
197
+ };
198
+ // -- identity ---------------------------------------------------------
199
+ if (componentId && (componentIdCounts[componentId] || 0) > 1) {
200
+ addNodeIssue({
201
+ rule: WorkflowLintRule.DuplicateComponentId,
202
+ severity: WorkflowLintSeverity.Error,
203
+ message: `More than one step has the id "${componentId}". Ids must be unique — otherwise the steps overwrite each other's results and any reference to "${componentId}" is ambiguous.`,
204
+ });
205
+ }
206
+ if (componentId && componentId.includes(".")) {
207
+ addNodeIssue({
208
+ rule: WorkflowLintRule.ComponentIdContainsDot,
209
+ severity: WorkflowLintSeverity.Error,
210
+ message: `The id "${componentId}" contains a dot. References are split on dots, so no other step can read this one's results. Use dashes instead.`,
211
+ });
212
+ }
213
+ // -- reachability ------------------------------------------------------
214
+ if (data.componentType !== ComponentType.Trigger &&
215
+ triggerNodes.length > 0 &&
216
+ !reachableFromTrigger.has(node.id)) {
217
+ addNodeIssue({
218
+ rule: WorkflowLintRule.UnreachableComponent,
219
+ severity: WorkflowLintSeverity.Warning,
220
+ message: "Nothing connects to this step from the trigger, so it will never run.",
221
+ });
222
+ }
223
+ // -- arguments ---------------------------------------------------------
224
+ const argumentMetadata = data.metadata.arguments || [];
225
+ for (const argument of argumentMetadata) {
226
+ const value = argumentValues[argument.id];
227
+ if (argument.required && isEmptyArgumentValue(value)) {
228
+ addNodeIssue({
229
+ rule: WorkflowLintRule.MissingRequiredArgument,
230
+ severity: WorkflowLintSeverity.Error,
231
+ argumentId: argument.id,
232
+ message: `"${argument.name}" is required but empty.`,
233
+ });
234
+ continue;
235
+ }
236
+ if (isEmptyArgumentValue(value)) {
237
+ continue;
238
+ }
239
+ if (JSON_DOCUMENT_INPUT_TYPES.includes(argument.type)) {
240
+ const jsonCheck = checkJSONSyntax(value, {
241
+ allowJSON5: isJSON5ToleratedInputType(argument.type),
242
+ });
243
+ if (!jsonCheck.isValid) {
244
+ addNodeIssue({
245
+ rule: WorkflowLintRule.InvalidJSON,
246
+ severity: WorkflowLintSeverity.Error,
247
+ argumentId: argument.id,
248
+ message: `"${argument.name}" is not valid JSON. ${jsonCheck.errorMessage}`,
249
+ });
250
+ }
251
+ }
252
+ // -- references ------------------------------------------------------
253
+ for (const text of collectArgumentStrings(value)) {
254
+ const expressions = parseTemplateExpressions(text);
255
+ for (const expression of expressions) {
256
+ if (expression.kind !== TemplateExpressionKind.Reference) {
257
+ continue;
258
+ }
259
+ /*
260
+ * Inside a loop, VMAPI resolves against the current array element
261
+ * before the storage map, so a bare {{status}} is correct there and
262
+ * cannot be checked from here.
263
+ */
264
+ if (expression.isInsideEachBlock) {
265
+ continue;
266
+ }
267
+ /*
268
+ * At the top level the runtime looks the path up exactly as written
269
+ * (VMAPI.replaceValueInPlace passes the raw capture to deepFind), so
270
+ * a stray space makes the reference resolve to nothing and the braces
271
+ * are shipped as literal text. Nothing about the rendered workflow
272
+ * hints at it, which makes this worth its own message rather than
273
+ * folding it into "unknown reference".
274
+ */
275
+ /*
276
+ * Every argument is templated, including the JavaScript component's
277
+ * source, and JavaScript can legitimately produce a {{...}} match on
278
+ * one line. Only complain about captures that were plausibly meant
279
+ * to be references.
280
+ */
281
+ if (!looksLikeReferencePath(expression.innerRaw)) {
282
+ continue;
283
+ }
284
+ if (expression.innerRaw !== expression.inner) {
285
+ addNodeIssue({
286
+ rule: WorkflowLintRule.ReferenceHasWhitespace,
287
+ severity: WorkflowLintSeverity.Error,
288
+ argumentId: argument.id,
289
+ message: `"${argument.name}" contains ${expression.raw}, which has a space inside the braces. Spaces are not trimmed here, so this resolves to nothing — write it as {{${expression.inner}}}.`,
290
+ });
291
+ continue;
292
+ }
293
+ const parsed = parseReferencePath(expression.inner);
294
+ if (parsed.rootType === ReferenceRootType.Unknown) {
295
+ addNodeIssue({
296
+ rule: WorkflowLintRule.UnknownReferenceRoot,
297
+ severity: WorkflowLintSeverity.Error,
298
+ argumentId: argument.id,
299
+ message: `"${argument.name}" refers to ${expression.raw}, but ${parsed.reason}. Nothing will be substituted and the text will be sent as-is.`,
300
+ });
301
+ continue;
302
+ }
303
+ if (parsed.rootType !== ReferenceRootType.ComponentReturnValue) {
304
+ // A variable reference — well-formed. Existence needs the API.
305
+ continue;
306
+ }
307
+ const referencedComponentId = parsed.componentId;
308
+ const referencedNode = nodesByComponentId[referencedComponentId];
309
+ if (!referencedNode) {
310
+ addNodeIssue({
311
+ rule: WorkflowLintRule.UnknownReferencedComponent,
312
+ severity: WorkflowLintSeverity.Error,
313
+ argumentId: argument.id,
314
+ message: `"${argument.name}" refers to a step called "${referencedComponentId}", but no step in this workflow has that id.`,
315
+ });
316
+ continue;
317
+ }
318
+ const returnValueId = parsed.returnValueId;
319
+ const returnValues = referencedNode.data.metadata.returnValues || [];
320
+ const hasReturnValue = returnValues.some((returnValue) => {
321
+ return returnValue.id === returnValueId;
322
+ });
323
+ if (!hasReturnValue) {
324
+ addNodeIssue({
325
+ rule: WorkflowLintRule.UnknownReferencedReturnValue,
326
+ severity: WorkflowLintSeverity.Error,
327
+ argumentId: argument.id,
328
+ message: `"${argument.name}" reads "${returnValueId}" from step "${referencedComponentId}", but that step does not return anything by that name.`,
329
+ });
330
+ continue;
331
+ }
332
+ if (referencedNode.id === node.id) {
333
+ addNodeIssue({
334
+ rule: WorkflowLintRule.SelfReference,
335
+ severity: WorkflowLintSeverity.Error,
336
+ argumentId: argument.id,
337
+ message: `"${argument.name}" refers to this step's own results, which do not exist yet while its settings are being read.`,
338
+ });
339
+ continue;
340
+ }
341
+ /*
342
+ * A step that is downstream of this one has definitively not run
343
+ * when this step's arguments are resolved, so the reference is
344
+ * always empty. (The converse is not true — the runner's queue is
345
+ * FIFO across branches, so a step on a parallel branch may well have
346
+ * run. Only the unambiguous direction is reported.)
347
+ */
348
+ if (getDescendants(node.id).has(referencedNode.id)) {
349
+ addNodeIssue({
350
+ rule: WorkflowLintRule.ForwardReference,
351
+ severity: WorkflowLintSeverity.Error,
352
+ argumentId: argument.id,
353
+ message: `"${argument.name}" reads results from "${referencedComponentId}", but that step runs after this one, so it has no results yet.`,
354
+ });
355
+ continue;
356
+ }
357
+ if (triggerNodes.length > 0 &&
358
+ !reachableFromTrigger.has(referencedNode.id)) {
359
+ addNodeIssue({
360
+ rule: WorkflowLintRule.ReferenceToUnreachableComponent,
361
+ severity: WorkflowLintSeverity.Warning,
362
+ argumentId: argument.id,
363
+ message: `"${argument.name}" reads results from "${referencedComponentId}", which is not connected to the trigger and so never runs.`,
364
+ });
365
+ }
366
+ }
367
+ }
368
+ }
369
+ }
370
+ /* ---- roll up ----------------------------------------------------------- */
371
+ const errorsByNodeId = {};
372
+ let errorCount = 0;
373
+ let warningCount = 0;
374
+ for (const issue of issues) {
375
+ if (issue.severity === WorkflowLintSeverity.Error) {
376
+ errorCount++;
377
+ }
378
+ else {
379
+ warningCount++;
380
+ }
381
+ if (!issue.nodeId) {
382
+ continue;
383
+ }
384
+ errorsByNodeId[issue.nodeId] = errorsByNodeId[issue.nodeId]
385
+ ? `${errorsByNodeId[issue.nodeId]}\n${issue.message}`
386
+ : issue.message;
387
+ }
388
+ return {
389
+ issues: issues,
390
+ errorsByNodeId: errorsByNodeId,
391
+ errorCount: errorCount,
392
+ warningCount: warningCount,
393
+ };
394
+ };
395
+ export default lintWorkflowGraph;
396
+ //# sourceMappingURL=GraphLint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GraphLint.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/GraphLint.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,225 @@
1
+ /*
2
+ * A row-based editor for the two workflow arguments that are keyed on a
3
+ * model's columns: the Query that picks which records a component acts on,
4
+ * and the record of values a create/update writes.
5
+ *
6
+ * Both were bare JSON editors, with the column names — and, for a query, the
7
+ * operator syntax — left entirely to memory. The description on those
8
+ * arguments had to carry a hint about "_id" versus "id" precisely because
9
+ * nothing else told the builder what the columns were called.
10
+ *
11
+ * Everything needed to do better already existed: /model-schema/:tableName
12
+ * knows the columns, and DictionaryForm's operator mode emits exactly the
13
+ * {_type, value} shape that JSONFunctions.deserialize hydrates on the server
14
+ * (FindManyBaseModel and friends). This wires the two together, and keeps a
15
+ * JSON escape hatch for the values rows cannot express.
16
+ */
17
+ import CodeEditor from "../CodeEditor/CodeEditor";
18
+ import ComponentLoader from "../ComponentLoader/ComponentLoader";
19
+ import DictionaryForm, { ValueType } from "../Dictionary/Dictionary";
20
+ import Icon from "../Icon/Icon";
21
+ import { findColumn, useModelSchema, } from "./ModelSchema";
22
+ import CodeType from "../../../Types/Code/CodeType";
23
+ import IconProp from "../../../Types/Icon/IconProp";
24
+ import { ObjectType } from "../../../Types/JSON";
25
+ import React, { useMemo, useRef, useState, } from "react";
26
+ export var ModelColumnEditorMode;
27
+ (function (ModelColumnEditorMode) {
28
+ /** Conditions that select records: column, operator, value. */
29
+ ModelColumnEditorMode["Query"] = "Query";
30
+ /** Values to write: column, value. No operators — you cannot save a ">". */
31
+ ModelColumnEditorMode["Record"] = "Record";
32
+ })(ModelColumnEditorMode || (ModelColumnEditorMode = {}));
33
+ /*
34
+ * Operator wrappers the row editor can show. Anything else in a stored query
35
+ * (an InBetween, a relation sub-object, a raw QueryHelper construct) keeps the
36
+ * JSON editor rather than being silently flattened.
37
+ */
38
+ const REPRESENTABLE_OPERATOR_TYPES = [
39
+ ObjectType.EqualTo,
40
+ ObjectType.NotEqual,
41
+ ObjectType.Search,
42
+ ObjectType.NotContains,
43
+ ObjectType.StartsWith,
44
+ ObjectType.EndsWith,
45
+ ObjectType.GreaterThan,
46
+ ObjectType.GreaterThanOrEqual,
47
+ ObjectType.LessThan,
48
+ ObjectType.LessThanOrEqual,
49
+ ObjectType.IsNull,
50
+ ObjectType.NotNull,
51
+ ObjectType.Includes,
52
+ ObjectType.IncludesNone,
53
+ ];
54
+ const normalizeInitialValue = (value) => {
55
+ if (value === null || value === undefined || value === "") {
56
+ return { text: "", parsed: {} };
57
+ }
58
+ if (typeof value === "object" && !Array.isArray(value)) {
59
+ return { text: JSON.stringify(value, null, 2), parsed: value };
60
+ }
61
+ if (typeof value !== "string") {
62
+ return { text: String(value), parsed: null };
63
+ }
64
+ try {
65
+ const parsed = JSON.parse(value);
66
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
67
+ return { text: value, parsed: parsed };
68
+ }
69
+ return { text: value, parsed: null };
70
+ }
71
+ catch (_a) {
72
+ return { text: value, parsed: null };
73
+ }
74
+ };
75
+ /**
76
+ * Can this value be shown as rows without losing anything?
77
+ *
78
+ * Deliberately conservative: when in doubt the JSON editor stays, because a
79
+ * value silently rewritten into something that means something else is far
80
+ * worse than one the builder has to keep editing as text.
81
+ */
82
+ export const classifyColumnValueCompatibility = (parsed, columns, mode) => {
83
+ if (parsed === null) {
84
+ return {
85
+ compatible: false,
86
+ reasons: ["The current value isn't a JSON object."],
87
+ };
88
+ }
89
+ const reasons = [];
90
+ for (const key of Object.keys(parsed)) {
91
+ /*
92
+ * Columns are only checked when the schema actually loaded. An unknown key
93
+ * is worth saying out loud — it is the "id" versus "_id" mistake — but it
94
+ * does not force the JSON editor, since the runner accepts column names
95
+ * this endpoint does not surface.
96
+ */
97
+ if (columns.length > 0 && !findColumn(columns, key)) {
98
+ reasons.push(`"${key}" isn't a known column on this model.`);
99
+ }
100
+ const value = parsed[key];
101
+ if (value === null) {
102
+ continue;
103
+ }
104
+ if (typeof value === "string" ||
105
+ typeof value === "number" ||
106
+ typeof value === "boolean") {
107
+ continue;
108
+ }
109
+ if (Array.isArray(value)) {
110
+ reasons.push(`"${key}" holds a list. Use the "is any of" operator instead, or keep editing as JSON.`);
111
+ continue;
112
+ }
113
+ if (typeof value === "object") {
114
+ const objectType = value["_type"];
115
+ if (mode === ModelColumnEditorMode.Query &&
116
+ typeof objectType === "string" &&
117
+ REPRESENTABLE_OPERATOR_TYPES.includes(objectType)) {
118
+ continue;
119
+ }
120
+ if (typeof objectType === "string") {
121
+ reasons.push(`"${key}" uses ${objectType}, which the rows can't show.`);
122
+ continue;
123
+ }
124
+ reasons.push(`"${key}" holds a nested record, which the rows can't show.`);
125
+ continue;
126
+ }
127
+ reasons.push(`"${key}" has an unexpected value.`);
128
+ }
129
+ /*
130
+ * An unknown column name is a warning, not a reason to lock the editor —
131
+ * the builder can still fix it in the row that shows it.
132
+ */
133
+ const blocking = reasons.filter((reason) => {
134
+ return !reason.includes("isn't a known column");
135
+ });
136
+ return { compatible: blocking.length === 0, reasons: reasons };
137
+ };
138
+ /**
139
+ * The rows, as the string stored on the workflow argument.
140
+ *
141
+ * Empty collapses to "" rather than "{}" so a required argument still reads as
142
+ * empty to form validation and to the graph linter.
143
+ */
144
+ export const buildColumnValueJson = (value) => {
145
+ const entries = {};
146
+ for (const key of Object.keys(value)) {
147
+ if (key.trim() === "") {
148
+ continue;
149
+ }
150
+ entries[key] = value[key];
151
+ }
152
+ if (Object.keys(entries).length === 0) {
153
+ return "";
154
+ }
155
+ /*
156
+ * The operator wrappers serialize themselves through toJSON() into
157
+ * {_type, value}, which is exactly what the server rehydrates with
158
+ * JSONFunctions.deserialize.
159
+ */
160
+ return JSON.stringify(entries);
161
+ };
162
+ const ModelColumnEditor = (props) => {
163
+ const schema = useModelSchema(props.tableName);
164
+ const isQuery = props.mode === ModelColumnEditorMode.Query;
165
+ const initial = useMemo(() => {
166
+ return normalizeInitialValue(props.initialValue);
167
+ }, []);
168
+ const [jsonText, setJsonText] = useState(initial.text);
169
+ const [viewMode, setViewMode] = useState("builder");
170
+ /*
171
+ * The row editor is uncontrolled after mount (DictionaryForm seeds itself
172
+ * once), so the initial value is captured rather than recomputed.
173
+ */
174
+ const initialRows = useRef((initial.parsed || {}));
175
+ const compatibility = useMemo(() => {
176
+ return classifyColumnValueCompatibility(initial.parsed, schema.columns || [], props.mode);
177
+ }, [schema.columns, props.mode]);
178
+ const columnKeys = useMemo(() => {
179
+ return (schema.columns || []).map((column) => {
180
+ return column.id;
181
+ });
182
+ }, [schema.columns]);
183
+ if (schema.isLoading) {
184
+ return React.createElement(ComponentLoader, null);
185
+ }
186
+ const isLockedToJson = !compatibility.compatible;
187
+ const effectiveMode = isLockedToJson ? "json" : viewMode;
188
+ const onJsonChange = (value) => {
189
+ setJsonText(value);
190
+ props.onChange(value);
191
+ };
192
+ const onRowsChange = (value) => {
193
+ const asJson = buildColumnValueJson(value);
194
+ setJsonText(asJson);
195
+ props.onChange(asJson);
196
+ };
197
+ return (React.createElement("div", null,
198
+ schema.error && (React.createElement("p", { className: "text-sm text-amber-600 mb-2" },
199
+ "Couldn't load this model's columns (",
200
+ schema.error,
201
+ "). You can still write the query as JSON.")),
202
+ isLockedToJson && compatibility.reasons.length > 0 && (React.createElement("div", { className: "mb-2 rounded-md border border-amber-200 bg-amber-50 p-3" },
203
+ React.createElement("p", { className: "text-sm text-amber-800" }, "Editing as JSON, because:"),
204
+ React.createElement("ul", { className: "mt-1 list-disc pl-5 text-sm text-amber-700" }, compatibility.reasons.map((reason, i) => {
205
+ return React.createElement("li", { key: i }, reason);
206
+ })))),
207
+ !isLockedToJson && compatibility.reasons.length > 0 && (React.createElement("div", { className: "mb-2 rounded-md border border-amber-200 bg-amber-50 p-3" },
208
+ React.createElement("ul", { className: "list-disc pl-5 text-sm text-amber-700" }, compatibility.reasons.map((reason, i) => {
209
+ return React.createElement("li", { key: i }, reason);
210
+ })))),
211
+ effectiveMode === "builder" ? (React.createElement(DictionaryForm, { keys: columnKeys, enableOperators: isQuery, valueTypes: [ValueType.Text, ValueType.Number, ValueType.Boolean], addButtonSuffix: isQuery ? "condition" : "field", keyPlaceholder: "Column", valuePlaceholder: "Value", initialValue: initialRows.current, onChange: onRowsChange })) : (React.createElement(CodeEditor, { type: CodeType.JSON, tabIndex: props.tabIndex, error: props.error, initialValue: initial.text, value: jsonText, placeholder: props.placeholder, onChange: onJsonChange })),
212
+ !isLockedToJson && (React.createElement("div", { className: "mt-2" },
213
+ React.createElement("button", { type: "button", className: "text-sm underline text-blue-500 hover:text-blue-600 cursor-pointer inline-flex items-center gap-1", onClick: () => {
214
+ setViewMode(effectiveMode === "builder" ? "json" : "builder");
215
+ } },
216
+ React.createElement(Icon, { icon: IconProp.Code, className: "h-3.5 w-3.5" }),
217
+ effectiveMode === "builder"
218
+ ? "Edit as JSON"
219
+ : isQuery
220
+ ? "Back to conditions"
221
+ : "Back to fields"))),
222
+ props.error && effectiveMode === "builder" && (React.createElement("p", { className: "mt-1 text-sm text-red-400" }, props.error))));
223
+ };
224
+ export default ModelColumnEditor;
225
+ //# sourceMappingURL=ModelColumnEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ModelColumnEditor.js","sourceRoot":"","sources":["../../../../../UI/Components/Workflow/ModelColumnEditor.tsx"],"names":[],"mappings":"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"}