@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,104 @@
1
+ /*
2
+ * A structured record of what each step of a workflow run actually did.
3
+ *
4
+ * The runner has always known this — it logs the arguments it resolved, the
5
+ * values a component returned, and which out port it took — but it flattened
6
+ * all of it into one newline-joined string, so the only way to answer "what did
7
+ * step three receive" was to read the whole blob. Keeping the same information
8
+ * as data lets the run be read as a list of steps, and lets a step be matched
9
+ * back to the node it came from on the canvas.
10
+ *
11
+ * The shapes live in Common/Types because the runner writes them, the API
12
+ * returns them, and the dashboard renders them.
13
+ */
14
+ export var WorkflowStepStatus;
15
+ (function (WorkflowStepStatus) {
16
+ WorkflowStepStatus["Success"] = "Success";
17
+ WorkflowStepStatus["Error"] = "Error";
18
+ })(WorkflowStepStatus || (WorkflowStepStatus = {}));
19
+ /*
20
+ * A run is bounded by cycle detection, but a workflow that suspends and resumes
21
+ * accumulates across resumes, and a single value can be an entire HTTP response
22
+ * body. Both are capped: the row is written on every status change, and an
23
+ * unbounded trace would turn each of those writes into a large one.
24
+ */
25
+ export const MAX_TRACE_STEPS = 100;
26
+ export const MAX_TRACE_VALUE_LENGTH = 4000;
27
+ export const TRUNCATED_VALUE_SUFFIX = "… (truncated)";
28
+ /**
29
+ * Shrink one recorded value to something a row can hold.
30
+ *
31
+ * Strings are cut; anything structured is measured by its JSON length and
32
+ * replaced wholesale when it is too big, because cutting a serialized object in
33
+ * half produces text that looks like data but cannot be parsed.
34
+ */
35
+ export const truncateTraceValue = (value) => {
36
+ if (typeof value === "string") {
37
+ if (value.length <= MAX_TRACE_VALUE_LENGTH) {
38
+ return value;
39
+ }
40
+ return value.slice(0, MAX_TRACE_VALUE_LENGTH) + TRUNCATED_VALUE_SUFFIX;
41
+ }
42
+ if (value === null || value === undefined) {
43
+ return value;
44
+ }
45
+ if (typeof value !== "object") {
46
+ return value;
47
+ }
48
+ let serialized;
49
+ try {
50
+ serialized = JSON.stringify(value);
51
+ }
52
+ catch (_a) {
53
+ // Circular or otherwise unserializable: say so rather than throwing.
54
+ return "[value could not be recorded]";
55
+ }
56
+ if (serialized.length <= MAX_TRACE_VALUE_LENGTH) {
57
+ return value;
58
+ }
59
+ return serialized.slice(0, MAX_TRACE_VALUE_LENGTH) + TRUNCATED_VALUE_SUFFIX;
60
+ };
61
+ export const truncateTraceValues = (values) => {
62
+ const truncated = {};
63
+ for (const key of Object.keys(values || {})) {
64
+ truncated[key] = truncateTraceValue(values[key]);
65
+ }
66
+ return truncated;
67
+ };
68
+ /**
69
+ * Add a step, keeping the trace within its cap.
70
+ *
71
+ * When the cap is reached the OLDEST steps are dropped: a run that failed is
72
+ * read from the end, and the step that broke it is the last one.
73
+ */
74
+ export const appendTraceStep = (trace, entry) => {
75
+ const steps = [...(trace.steps || []), entry];
76
+ if (steps.length <= MAX_TRACE_STEPS) {
77
+ return Object.assign(Object.assign({}, trace), { steps: steps });
78
+ }
79
+ return Object.assign(Object.assign({}, trace), { steps: steps.slice(steps.length - MAX_TRACE_STEPS), truncated: true });
80
+ };
81
+ export const emptyTrace = () => {
82
+ return { steps: [] };
83
+ };
84
+ /**
85
+ * Read a trace back off a row, tolerating anything that is not one.
86
+ *
87
+ * Old runs predate the column and rows can be written by an older build, so
88
+ * this never throws — a trace it cannot understand reads as an empty one and
89
+ * the viewer falls back to the raw log.
90
+ */
91
+ export const parseTrace = (value) => {
92
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
93
+ return emptyTrace();
94
+ }
95
+ const steps = value["steps"];
96
+ if (!Array.isArray(steps)) {
97
+ return emptyTrace();
98
+ }
99
+ return {
100
+ steps: steps,
101
+ truncated: Boolean(value["truncated"]),
102
+ };
103
+ };
104
+ //# sourceMappingURL=StepTrace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StepTrace.js","sourceRoot":"","sources":["../../../../Types/Workflow/StepTrace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,326 @@
1
+ /*
2
+ * Parsing helpers for the {{...}} template syntax that workflow arguments use.
3
+ *
4
+ * The runtime implementation lives in Common/Server/Utils/VM/VMAPI.ts
5
+ * (replaceValueInPlace, expandEachLoops, deepFind). Everything in this file
6
+ * mirrors that behaviour so the builder can warn about a broken reference
7
+ * before a run does — VMAPI deliberately skips a reference it cannot resolve
8
+ * ("Skip replacement if the variable is not found in the storageMap"), which
9
+ * means a typo like {{local.componets.api-get-1.returnValues.response-body}}
10
+ * is sent as literal text in the outgoing request and the run still reports
11
+ * Success. That silence is the bug this module exists to end.
12
+ *
13
+ * This lives in Common/Types (not Common/UI) because both the builder and the
14
+ * server-side runner need it, and Common/Types has no UI or server deps.
15
+ */
16
+ import JSON5 from "json5";
17
+ export const getTemplateExpressionRegex = () => {
18
+ return /{{(.*?)}}/g;
19
+ };
20
+ export var TemplateExpressionKind;
21
+ (function (TemplateExpressionKind) {
22
+ /** A value reference, e.g. {{local.variables.apiKey}}. */
23
+ TemplateExpressionKind["Reference"] = "Reference";
24
+ /** The opening tag of a loop, e.g. {{#each local.components.x.returnValues.items}}. */
25
+ TemplateExpressionKind["EachOpen"] = "EachOpen";
26
+ /** The closing tag of a loop: {{/each}}. */
27
+ TemplateExpressionKind["EachClose"] = "EachClose";
28
+ /** The loop index helper: {{@index}}. */
29
+ TemplateExpressionKind["LoopIndex"] = "LoopIndex";
30
+ /** The current primitive element inside a loop: {{this}}. */
31
+ TemplateExpressionKind["LoopThis"] = "LoopThis";
32
+ })(TemplateExpressionKind || (TemplateExpressionKind = {}));
33
+ const classifyExpression = (inner) => {
34
+ if (inner.startsWith("#each")) {
35
+ return TemplateExpressionKind.EachOpen;
36
+ }
37
+ if (inner === "/each") {
38
+ return TemplateExpressionKind.EachClose;
39
+ }
40
+ if (inner === "@index") {
41
+ return TemplateExpressionKind.LoopIndex;
42
+ }
43
+ if (inner === "this") {
44
+ return TemplateExpressionKind.LoopThis;
45
+ }
46
+ return TemplateExpressionKind.Reference;
47
+ };
48
+ /**
49
+ * Every {{...}} expression in `value`, in source order, each tagged with what
50
+ * it is and whether it sits inside a loop body.
51
+ */
52
+ export const parseTemplateExpressions = (value) => {
53
+ if (!value || typeof value !== "string") {
54
+ return [];
55
+ }
56
+ const expressions = [];
57
+ const regex = getTemplateExpressionRegex();
58
+ let match = null;
59
+ let eachDepth = 0;
60
+ while ((match = regex.exec(value)) !== null) {
61
+ const raw = match[0];
62
+ const innerRaw = match[1] || "";
63
+ const inner = innerRaw.trim();
64
+ const kind = classifyExpression(inner);
65
+ /*
66
+ * A closing tag is not itself "inside" the block it closes, and an opening
67
+ * tag is not inside the block it opens — but the array path on an opening
68
+ * tag IS resolved against the enclosing scope, so nested opens still count
69
+ * as inside their parent.
70
+ */
71
+ if (kind === TemplateExpressionKind.EachClose) {
72
+ eachDepth = Math.max(0, eachDepth - 1);
73
+ }
74
+ expressions.push({
75
+ raw: raw,
76
+ inner: inner,
77
+ innerRaw: innerRaw,
78
+ kind: kind,
79
+ startIndex: match.index,
80
+ endIndex: match.index + raw.length,
81
+ isInsideEachBlock: eachDepth > 0,
82
+ });
83
+ if (kind === TemplateExpressionKind.EachOpen) {
84
+ eachDepth++;
85
+ }
86
+ }
87
+ return expressions;
88
+ };
89
+ /**
90
+ * True when the value contains a loop. A loop expands to a variable number of
91
+ * repetitions of its body, so the shape of the final string is not knowable
92
+ * statically — callers that check structure (e.g. JSON validity) must bail out.
93
+ */
94
+ export const hasEachBlock = (value) => {
95
+ if (!value || typeof value !== "string") {
96
+ return false;
97
+ }
98
+ return value.includes("{{#each") || value.includes("{{/each}}");
99
+ };
100
+ /*
101
+ * Substituted into a JSON document in place of every {{...}} expression before
102
+ * the document is parsed. `1` is chosen because it is simultaneously a legal
103
+ * JSON value (`{"n": {{x}}}` -> `{"n": 1}`), legal inside a string literal
104
+ * (`{"s": "{{x}}"}` -> `{"s": "1"}`), and legal as an object key
105
+ * (`{"{{x}}": 2}` -> `{"1": 2}`). Any of those three is a real thing people
106
+ * write, and all three have to survive masking or the check reports a
107
+ * syntax error where none exists.
108
+ */
109
+ const TEMPLATE_MASK_TOKEN = "1";
110
+ /**
111
+ * Replace every {{...}} expression with a neutral literal, so what remains can
112
+ * be checked for JSON syntax without the (unknown, run-time) substituted
113
+ * values.
114
+ */
115
+ export const maskTemplateExpressions = (value) => {
116
+ if (!value || typeof value !== "string") {
117
+ return value;
118
+ }
119
+ return value.replace(getTemplateExpressionRegex(), TEMPLATE_MASK_TOKEN);
120
+ };
121
+ /**
122
+ * Is `value` a JSON document, once its {{...}} placeholders are accounted for?
123
+ *
124
+ * Deliberately permissive. It returns invalid only for a string that cannot
125
+ * become JSON no matter what the placeholders resolve to, because a false
126
+ * positive here disables the Save button on a workflow that actually works.
127
+ */
128
+ export const checkJSONSyntax = (value, options) => {
129
+ const skipped = {
130
+ isValid: true,
131
+ errorMessage: null,
132
+ wasSkipped: true,
133
+ };
134
+ /*
135
+ * Not a string: the field already holds a parsed object (the Dictionary
136
+ * editor and imported graphs both produce these). Nothing to parse.
137
+ */
138
+ if (typeof value !== "string") {
139
+ return skipped;
140
+ }
141
+ // Empty is the job of the required-field check, not this one.
142
+ if (value.trim() === "") {
143
+ return skipped;
144
+ }
145
+ /*
146
+ * A loop emits its body once per array element, so the document's structure
147
+ * depends on data that only exists at run time. Checking the unexpanded text
148
+ * would flag every correct loop ever written.
149
+ */
150
+ if (hasEachBlock(value)) {
151
+ return skipped;
152
+ }
153
+ const masked = maskTemplateExpressions(value);
154
+ try {
155
+ if (options === null || options === void 0 ? void 0 : options.allowJSON5) {
156
+ JSON5.parse(masked);
157
+ }
158
+ else {
159
+ JSON.parse(masked);
160
+ }
161
+ return { isValid: true, errorMessage: null, wasSkipped: false };
162
+ }
163
+ catch (err) {
164
+ const parserMessage = err instanceof Error ? err.message : "Invalid JSON.";
165
+ return {
166
+ isValid: false,
167
+ errorMessage: parserMessage,
168
+ wasSkipped: false,
169
+ };
170
+ }
171
+ };
172
+ /* ------------------------------------------------------------------------ */
173
+ /* Reference paths */
174
+ /* ------------------------------------------------------------------------ */
175
+ export var ReferenceRootType;
176
+ (function (ReferenceRootType) {
177
+ ReferenceRootType["LocalVariable"] = "LocalVariable";
178
+ ReferenceRootType["GlobalVariable"] = "GlobalVariable";
179
+ ReferenceRootType["ComponentReturnValue"] = "ComponentReturnValue";
180
+ /** Well-formed-looking but not a root the runtime storage map has. */
181
+ ReferenceRootType["Unknown"] = "Unknown";
182
+ })(ReferenceRootType || (ReferenceRootType = {}));
183
+ /**
184
+ * `items[0]` -> `items`. VMUtil.deepFind splits a path on "." and then looks
185
+ * for a `[index]` suffix on each segment, so the name to match against
186
+ * metadata is whatever precedes the bracket.
187
+ */
188
+ const stripArrayAccessor = (segment) => {
189
+ const bracketIndex = segment.indexOf("[");
190
+ if (bracketIndex === -1) {
191
+ return segment;
192
+ }
193
+ return segment.slice(0, bracketIndex);
194
+ };
195
+ /*
196
+ * Characters that appear in code but never in a reference path. A workflow's
197
+ * JavaScript component is templated like every other argument
198
+ * (RunWorkflow.getComponentArguments runs on all of them), so its source is
199
+ * scanned by the same regex — and JavaScript really can contain `{{` and `}}`
200
+ * on one line, e.g. `if (x) {{ return 1; }}`. Anything carrying these is code
201
+ * that happened to match, not a reference somebody typo'd, and reporting it
202
+ * would put a red badge on a component that works.
203
+ */
204
+ const NON_REFERENCE_CHARACTERS = /[{}()[\];=+*/&|!<>"'`,]/;
205
+ /**
206
+ * Whether a template capture was plausibly *meant* to be a value reference.
207
+ * Used to decide whether an unrecognized path is worth complaining about.
208
+ *
209
+ * Array accessors are stripped first, since `items[0]` is a legitimate path
210
+ * segment even though it contains brackets.
211
+ */
212
+ export const looksLikeReferencePath = (capture) => {
213
+ const trimmed = capture.trim();
214
+ if (trimmed === "") {
215
+ return false;
216
+ }
217
+ const withoutAccessors = trimmed.replace(/\[(\d+|last)\]/g, "");
218
+ return !NON_REFERENCE_CHARACTERS.test(withoutAccessors);
219
+ };
220
+ /**
221
+ * Break a reference path into the parts the builder can check against the
222
+ * graph. Mirrors the StorageMap shape built in RunWorkflow.getVariables:
223
+ *
224
+ * local.variables.<name>
225
+ * local.components.<componentId>.returnValues.<returnValueId>[...deeper]
226
+ * global.variables.<name>
227
+ *
228
+ * Anything past the return value id is a drill-in to whatever that value
229
+ * happens to contain at run time, so it is not inspected here.
230
+ */
231
+ export const parseReferencePath = (path) => {
232
+ if (path.trim() === "") {
233
+ return {
234
+ rootType: ReferenceRootType.Unknown,
235
+ reason: "the reference is empty",
236
+ };
237
+ }
238
+ const rawSegments = path.split(".").map((segment) => {
239
+ return segment.trim();
240
+ });
241
+ /*
242
+ * deepFind splits on "." and bails on the first empty key, so a doubled dot
243
+ * silently resolves to nothing. Catch it here rather than filtering the
244
+ * empties out, which would make "local..variables.x" look perfectly fine.
245
+ */
246
+ if (rawSegments.some((segment) => {
247
+ return segment.length === 0;
248
+ })) {
249
+ return {
250
+ rootType: ReferenceRootType.Unknown,
251
+ reason: "it has an empty part between two dots",
252
+ };
253
+ }
254
+ const segments = rawSegments;
255
+ const root = stripArrayAccessor(segments[0]);
256
+ if (root === "global") {
257
+ if (stripArrayAccessor(segments[1] || "") !== "variables") {
258
+ return {
259
+ rootType: ReferenceRootType.Unknown,
260
+ reason: '"global" must be followed by "variables"',
261
+ };
262
+ }
263
+ if (!segments[2]) {
264
+ return {
265
+ rootType: ReferenceRootType.Unknown,
266
+ reason: "no global variable name was given",
267
+ };
268
+ }
269
+ return {
270
+ rootType: ReferenceRootType.GlobalVariable,
271
+ variableName: stripArrayAccessor(segments[2]),
272
+ };
273
+ }
274
+ if (root !== "local") {
275
+ return {
276
+ rootType: ReferenceRootType.Unknown,
277
+ reason: `"${root}" is not a thing a reference can start with — use "local" or "global"`,
278
+ };
279
+ }
280
+ const second = stripArrayAccessor(segments[1] || "");
281
+ if (second === "variables") {
282
+ if (!segments[2]) {
283
+ return {
284
+ rootType: ReferenceRootType.Unknown,
285
+ reason: "no variable name was given",
286
+ };
287
+ }
288
+ return {
289
+ rootType: ReferenceRootType.LocalVariable,
290
+ variableName: stripArrayAccessor(segments[2]),
291
+ };
292
+ }
293
+ if (second !== "components") {
294
+ return {
295
+ rootType: ReferenceRootType.Unknown,
296
+ reason: `"local.${second}" is not valid — use "local.variables" or "local.components"`,
297
+ };
298
+ }
299
+ const componentId = stripArrayAccessor(segments[2] || "");
300
+ if (!componentId) {
301
+ return {
302
+ rootType: ReferenceRootType.Unknown,
303
+ reason: "no component id was given",
304
+ };
305
+ }
306
+ const third = stripArrayAccessor(segments[3] || "");
307
+ if (third !== "returnValues") {
308
+ return {
309
+ rootType: ReferenceRootType.Unknown,
310
+ reason: `"local.components.${componentId}" must be followed by "returnValues"`,
311
+ };
312
+ }
313
+ const returnValueId = stripArrayAccessor(segments[4] || "");
314
+ if (!returnValueId) {
315
+ return {
316
+ rootType: ReferenceRootType.Unknown,
317
+ reason: `no return value was named on "${componentId}"`,
318
+ };
319
+ }
320
+ return {
321
+ rootType: ReferenceRootType.ComponentReturnValue,
322
+ componentId: componentId,
323
+ returnValueId: returnValueId,
324
+ };
325
+ };
326
+ //# sourceMappingURL=TemplateSyntax.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TemplateSyntax.js","sourceRoot":"","sources":["../../../../Types/Workflow/TemplateSyntax.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,218 @@
1
+ /*
2
+ * Starter workflows.
3
+ *
4
+ * An empty canvas is a bad first lesson: the thing a new builder most needs to
5
+ * learn is how one step reads another's output, and nothing on a blank graph
6
+ * teaches it. Each template below is a small, working workflow whose whole
7
+ * point is to show a {{local.components.…}} reference in context.
8
+ *
9
+ * Every template here is deliberately runnable with no external configuration
10
+ * — no Slack token, no API key, no third-party account. Templates that need
11
+ * credentials belong in the docs, not in a one-click "start from this".
12
+ *
13
+ * The graphs are plain data in the same shape the builder saves and the JSON
14
+ * import reads, so a template is created through the ordinary Workflow create
15
+ * path (which denormalizes the trigger onto the row in
16
+ * WorkflowService.onCreateSuccess).
17
+ */
18
+ import ComponentID from "./ComponentID";
19
+ import { ComponentType, NodeType } from "./Component";
20
+ export const buildTemplateGraph = (spec, generateId) => {
21
+ const nodeIdByComponentId = {};
22
+ const nodes = spec.nodes.map((node) => {
23
+ const nodeId = generateId();
24
+ nodeIdByComponentId[node.componentId] = nodeId;
25
+ return {
26
+ id: nodeId,
27
+ type: "node",
28
+ position: node.position,
29
+ data: {
30
+ id: node.componentId,
31
+ nodeType: NodeType.Node,
32
+ componentType: node.componentType,
33
+ metadataId: node.metadataId,
34
+ internalId: generateId(),
35
+ error: "",
36
+ arguments: node.args || {},
37
+ returnValues: {},
38
+ },
39
+ };
40
+ });
41
+ const edges = spec.edges.map((edge) => {
42
+ return {
43
+ id: generateId(),
44
+ source: nodeIdByComponentId[edge.fromComponentId],
45
+ target: nodeIdByComponentId[edge.toComponentId],
46
+ sourceHandle: edge.fromPort,
47
+ targetHandle: "in",
48
+ };
49
+ });
50
+ return { nodes: nodes, edges: edges };
51
+ };
52
+ const TEMPLATE_DEFINITIONS = [
53
+ {
54
+ id: "manual-log",
55
+ name: "Log a message when run by hand",
56
+ description: "The smallest working workflow: a manual trigger and a step that writes a line to the run log.",
57
+ teaches: "How to run a workflow and where its output shows up.",
58
+ workflowName: "Log a message",
59
+ workflowDescription: "Runs on demand and writes a line to the run log. A good place to start.",
60
+ graph: {
61
+ nodes: [
62
+ {
63
+ componentId: "manual-1",
64
+ metadataId: ComponentID.Manual,
65
+ componentType: ComponentType.Trigger,
66
+ position: { x: 100, y: 100 },
67
+ },
68
+ {
69
+ componentId: "log-1",
70
+ metadataId: ComponentID.Log,
71
+ componentType: ComponentType.Component,
72
+ position: { x: 100, y: 300 },
73
+ args: {
74
+ value: "Hello from OneUptime. This workflow ran.",
75
+ },
76
+ },
77
+ ],
78
+ edges: [
79
+ {
80
+ fromComponentId: "manual-1",
81
+ toComponentId: "log-1",
82
+ fromPort: "success",
83
+ },
84
+ ],
85
+ },
86
+ },
87
+ {
88
+ id: "webhook-echo",
89
+ name: "Echo what a webhook sent",
90
+ description: "Takes the body posted to this workflow's webhook and writes it back out to the log.",
91
+ /*
92
+ * The reason this template exists: the log message is a reference, not
93
+ * text, and seeing that in place is the fastest way to understand the
94
+ * whole substitution model.
95
+ */
96
+ teaches: "How one step reads another's output, using {{local.components...}}.",
97
+ workflowName: "Echo webhook body",
98
+ workflowDescription: "Writes whatever was posted to this workflow's webhook into the run log.",
99
+ graph: {
100
+ nodes: [
101
+ {
102
+ componentId: "webhook-1",
103
+ metadataId: ComponentID.Webhook,
104
+ componentType: ComponentType.Trigger,
105
+ position: { x: 100, y: 100 },
106
+ },
107
+ {
108
+ componentId: "log-1",
109
+ metadataId: ComponentID.Log,
110
+ componentType: ComponentType.Component,
111
+ position: { x: 100, y: 300 },
112
+ args: {
113
+ value: "Webhook received: {{local.components.webhook-1.returnValues.request-body}}",
114
+ },
115
+ },
116
+ ],
117
+ edges: [
118
+ {
119
+ fromComponentId: "webhook-1",
120
+ toComponentId: "log-1",
121
+ fromPort: "out",
122
+ },
123
+ ],
124
+ },
125
+ },
126
+ {
127
+ id: "scheduled-check",
128
+ name: "Call an API on a schedule",
129
+ description: "Runs every hour, calls a URL, and logs whether it came back OK — with separate paths for success and failure.",
130
+ teaches: "How a schedule works, and how a step's Success and Error ports branch.",
131
+ workflowName: "Hourly API check",
132
+ workflowDescription: "Calls a URL every hour and logs the outcome. Point the URL at something of yours.",
133
+ graph: {
134
+ nodes: [
135
+ {
136
+ componentId: "schedule-1",
137
+ metadataId: ComponentID.Schedule,
138
+ componentType: ComponentType.Trigger,
139
+ position: { x: 100, y: 100 },
140
+ args: {
141
+ schedule: "0 * * * *",
142
+ },
143
+ },
144
+ {
145
+ componentId: "api-get-1",
146
+ metadataId: ComponentID.ApiGet,
147
+ componentType: ComponentType.Component,
148
+ position: { x: 100, y: 300 },
149
+ args: {
150
+ url: "https://api.github.com/zen",
151
+ },
152
+ },
153
+ {
154
+ componentId: "log-ok",
155
+ metadataId: ComponentID.Log,
156
+ componentType: ComponentType.Component,
157
+ position: { x: -100, y: 500 },
158
+ args: {
159
+ value: "Responded {{local.components.api-get-1.returnValues.response-status}}: {{local.components.api-get-1.returnValues.response-body}}",
160
+ },
161
+ },
162
+ {
163
+ componentId: "log-failed",
164
+ metadataId: ComponentID.Log,
165
+ componentType: ComponentType.Component,
166
+ position: { x: 300, y: 500 },
167
+ args: {
168
+ value: "Call failed: {{local.components.api-get-1.returnValues.error}}",
169
+ },
170
+ },
171
+ ],
172
+ edges: [
173
+ {
174
+ fromComponentId: "schedule-1",
175
+ toComponentId: "api-get-1",
176
+ fromPort: "execute",
177
+ },
178
+ {
179
+ fromComponentId: "api-get-1",
180
+ toComponentId: "log-ok",
181
+ fromPort: "success",
182
+ },
183
+ {
184
+ fromComponentId: "api-get-1",
185
+ toComponentId: "log-failed",
186
+ fromPort: "error",
187
+ },
188
+ ],
189
+ },
190
+ },
191
+ ];
192
+ export const getWorkflowTemplates = () => {
193
+ return TEMPLATE_DEFINITIONS.map((definition) => {
194
+ return {
195
+ id: definition.id,
196
+ name: definition.name,
197
+ description: definition.description,
198
+ teaches: definition.teaches,
199
+ workflowName: definition.workflowName,
200
+ workflowDescription: definition.workflowDescription,
201
+ };
202
+ });
203
+ };
204
+ export const getTemplateGraphSpec = (templateId) => {
205
+ const definition = TEMPLATE_DEFINITIONS.find((candidate) => {
206
+ return candidate.id === templateId;
207
+ });
208
+ return definition ? definition.graph : null;
209
+ };
210
+ export const buildGraphForTemplate = (templateId, generateId) => {
211
+ const spec = getTemplateGraphSpec(templateId);
212
+ if (!spec) {
213
+ return null;
214
+ }
215
+ return buildTemplateGraph(spec, generateId);
216
+ };
217
+ export default getWorkflowTemplates;
218
+ //# sourceMappingURL=Templates.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Templates.js","sourceRoot":"","sources":["../../../../Types/Workflow/Templates.ts"],"names":[],"mappings":"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"}