@livechat/platform-workflows 0.1.7 → 0.44.0-beta.v1
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/dist/chunk-6ZQIQVNX.mjs +33594 -0
- package/dist/chunk-OAUPCV3P.mjs +19 -0
- package/dist/config.d.mts +0 -4
- package/dist/config.d.ts +0 -4
- package/dist/config.js +6 -17
- package/dist/config.mjs +1 -2
- package/dist/constants.d.mts +921 -993
- package/dist/constants.d.ts +921 -993
- package/dist/constants.js +31411 -9497
- package/dist/constants.mjs +393 -10773
- package/dist/domain.d.mts +298 -0
- package/dist/domain.d.ts +298 -0
- package/dist/domain.js +35232 -0
- package/dist/domain.mjs +2975 -0
- package/dist/index.css +64 -73
- package/dist/index.d.mts +817 -21
- package/dist/index.d.ts +817 -21
- package/dist/index.js +56780 -21544
- package/dist/index.mjs +58180 -22037
- package/dist/tests.d.mts +140 -10
- package/dist/tests.d.ts +140 -10
- package/dist/tests.js +147 -17
- package/dist/tests.mjs +147 -19
- package/dist/types-BSdHiBvO.d.mts +440 -0
- package/dist/types-BSdHiBvO.d.ts +440 -0
- package/package.json +38 -30
- package/dist/chunk-BW4GCPXP.mjs +0 -20
- package/dist/chunk-EACC5D4G.mjs +0 -113
- package/dist/chunk-I4E63NIC.mjs +0 -24
- package/dist/chunk-OHDSKF3P.mjs +0 -193
- package/dist/chunk-PWFJOGII.mjs +0 -83
- package/dist/chunk-UQO6HYDU.mjs +0 -84
- package/dist/chunk-V3FK4SUN.mjs +0 -1606
- package/dist/chunk-WFVTCU6F.mjs +0 -24
- package/dist/chunk-WNNR3KXF.mjs +0 -1607
- package/dist/chunk-WS4FFM4M.mjs +0 -111
- package/dist/chunk-XIPVJOPR.mjs +0 -1621
- package/dist/chunk-YS3C7NY2.mjs +0 -1623
- package/dist/index-B3GBo8sA.d.mts +0 -98
- package/dist/index-B3GBo8sA.d.ts +0 -98
package/dist/domain.mjs
ADDED
|
@@ -0,0 +1,2975 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HELPDESK_REFERENCE_NAMES,
|
|
3
|
+
LIVECHAT_REFERENCE_NAMES,
|
|
4
|
+
OTHER_TYPES,
|
|
5
|
+
SYSTEM_AI_AGENT_TRIGGER_NAME,
|
|
6
|
+
SYSTEM_AWAIT_TASK_CONVERTER,
|
|
7
|
+
SYSTEM_CONDITION_TASK_CONVERTER,
|
|
8
|
+
SYSTEM_CONSTRUCT_TASK_CONVERTER,
|
|
9
|
+
SYSTEM_CONVERT_TASK_CONVERTER,
|
|
10
|
+
SYSTEM_FORK_TASK_CONVERTER,
|
|
11
|
+
SYSTEM_FOR_EACH_TASK_CONVERTER,
|
|
12
|
+
SYSTEM_JOIN_TASK_CONVERTER,
|
|
13
|
+
SYSTEM_LOOP_TASK_CONVERTER,
|
|
14
|
+
SYSTEM_MANUAL_TRIGGER_NAME,
|
|
15
|
+
SYSTEM_NOTIFY_AI_AGENT_TASK_CONVERTER,
|
|
16
|
+
SYSTEM_REASONING_TASK_CONVERTER,
|
|
17
|
+
SYSTEM_SCHEDULED_TRIGGER_NAME,
|
|
18
|
+
SYSTEM_SCRIPT_TASK_CONVERTER,
|
|
19
|
+
SYSTEM_SWITCH_CASE_TASK_CONVERTER,
|
|
20
|
+
SYSTEM_TASK_NAMES,
|
|
21
|
+
SYSTEM_TERMINATE_TASK_CONVERTER,
|
|
22
|
+
SYSTEM_WAIT_TASK_CONVERTER,
|
|
23
|
+
TEXTAPP_PRODUCT_NAME,
|
|
24
|
+
WORKFLOW_ACTION_TASK_TEMPLATE,
|
|
25
|
+
WORKFLOW_AGENT_TRIGGER_TEMPLATE,
|
|
26
|
+
WORKFLOW_HTTP_TASK_OUTPUT_SCHEMA,
|
|
27
|
+
WORKFLOW_HTTP_TASK_TEMPLATE,
|
|
28
|
+
WORKFLOW_MANUAL_TRIGGER_TEMPLATE,
|
|
29
|
+
WORKFLOW_SCHEDULED_TRIGGER_TEMPLATE,
|
|
30
|
+
WORKFLOW_SYSTEM_WEBHOOK_TRIGGER_TEMPLATE,
|
|
31
|
+
WORKFLOW_WEBHOOK_TRIGGER_TEMPLATE,
|
|
32
|
+
capitalizeFirstLetter,
|
|
33
|
+
collectSchemaRefs,
|
|
34
|
+
generateObjectFromSchema,
|
|
35
|
+
getConditionOperatorsForType,
|
|
36
|
+
getSpecification,
|
|
37
|
+
getWorkflowReferenceDefRef,
|
|
38
|
+
getWorkflowReferenceDefinitionByName,
|
|
39
|
+
getWorkflowReferenceDefinitionFromSchema,
|
|
40
|
+
getWorkflowSpecificationItemByReference,
|
|
41
|
+
jsonUtils,
|
|
42
|
+
notEmpty,
|
|
43
|
+
rawItemConfigs,
|
|
44
|
+
resolveDisplayType,
|
|
45
|
+
toSchemaPropertiesPath,
|
|
46
|
+
validatePathAgainstSchema,
|
|
47
|
+
workflowReferences,
|
|
48
|
+
workflowResources
|
|
49
|
+
} from "./chunk-6ZQIQVNX.mjs";
|
|
50
|
+
import {
|
|
51
|
+
getWorkflowsEnv
|
|
52
|
+
} from "./chunk-OAUPCV3P.mjs";
|
|
53
|
+
|
|
54
|
+
// src/domain/common/build.ts
|
|
55
|
+
import {
|
|
56
|
+
WorkflowCustomTaskName,
|
|
57
|
+
WorkflowItemKind,
|
|
58
|
+
WorkflowTaskType,
|
|
59
|
+
WorkflowTriggerType
|
|
60
|
+
} from "@livechat/developer-studio-api";
|
|
61
|
+
function buildTask(ctx, task) {
|
|
62
|
+
var _a;
|
|
63
|
+
const validTypes = Object.values(WorkflowTaskType);
|
|
64
|
+
if (!validTypes.includes(task.type)) {
|
|
65
|
+
ctx.errors.push(
|
|
66
|
+
`Unknown task type "${task.type}" for task "${task.name}". Valid types: ${validTypes.join(", ")}`
|
|
67
|
+
);
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
const config = ctx.spec.raw.items[task.name];
|
|
71
|
+
if (!config) {
|
|
72
|
+
ctx.errors.push(`Unknown task name: ${task.name}`);
|
|
73
|
+
return null;
|
|
74
|
+
}
|
|
75
|
+
if (config.kind !== WorkflowItemKind.Task) {
|
|
76
|
+
ctx.errors.push(`Invalid config found for: ${task.name}`);
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
if (task.type === WorkflowTaskType.http) {
|
|
80
|
+
return WORKFLOW_HTTP_TASK_TEMPLATE(
|
|
81
|
+
task.name,
|
|
82
|
+
task.taskReferenceName,
|
|
83
|
+
task.input,
|
|
84
|
+
void 0,
|
|
85
|
+
task.name === SYSTEM_TASK_NAMES.http
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
if (task.type === WorkflowTaskType.forkJoin) {
|
|
89
|
+
const targetForkTask = SYSTEM_FORK_TASK_CONVERTER(task);
|
|
90
|
+
return {
|
|
91
|
+
...targetForkTask,
|
|
92
|
+
forkTasks: task.input.map((branch) => buildTasks(ctx, branch))
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (task.type === WorkflowTaskType.switch) {
|
|
96
|
+
let targetSwitchTask = void 0;
|
|
97
|
+
if (task.name === WorkflowCustomTaskName.condition) {
|
|
98
|
+
targetSwitchTask = SYSTEM_CONDITION_TASK_CONVERTER(task);
|
|
99
|
+
} else if (task.name === WorkflowCustomTaskName.switchCase) {
|
|
100
|
+
targetSwitchTask = SYSTEM_SWITCH_CASE_TASK_CONVERTER(task);
|
|
101
|
+
} else {
|
|
102
|
+
ctx.errors.push("Unknown switch type");
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
const decisionCases = {};
|
|
106
|
+
for (const [caseName, caseTasks] of Object.entries(
|
|
107
|
+
task.input.decisionCases
|
|
108
|
+
)) {
|
|
109
|
+
decisionCases[caseName] = buildTasks(ctx, caseTasks);
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
...targetSwitchTask,
|
|
113
|
+
decisionCases,
|
|
114
|
+
defaultCase: buildTasks(ctx, (_a = task.input.defaultCase) != null ? _a : [])
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
if (task.type === WorkflowTaskType.wait) {
|
|
118
|
+
return SYSTEM_WAIT_TASK_CONVERTER(task);
|
|
119
|
+
}
|
|
120
|
+
if (task.type === WorkflowTaskType.terminate) {
|
|
121
|
+
return SYSTEM_TERMINATE_TASK_CONVERTER(task);
|
|
122
|
+
}
|
|
123
|
+
if (task.type === WorkflowTaskType.doWhile) {
|
|
124
|
+
let targetDoWhileTask = void 0;
|
|
125
|
+
if (task.name === WorkflowCustomTaskName.loop) {
|
|
126
|
+
targetDoWhileTask = SYSTEM_LOOP_TASK_CONVERTER(task);
|
|
127
|
+
} else if (task.name === WorkflowCustomTaskName.forEach) {
|
|
128
|
+
targetDoWhileTask = SYSTEM_FOR_EACH_TASK_CONVERTER(task);
|
|
129
|
+
} else {
|
|
130
|
+
ctx.errors.push("Unknown doWhile type");
|
|
131
|
+
return null;
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
...targetDoWhileTask,
|
|
135
|
+
loopOver: buildTasks(ctx, task.input.loopOver)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
if (task.type === WorkflowTaskType.inline) {
|
|
139
|
+
if (task.name === WorkflowCustomTaskName.script) {
|
|
140
|
+
return SYSTEM_SCRIPT_TASK_CONVERTER(task);
|
|
141
|
+
}
|
|
142
|
+
return {
|
|
143
|
+
name: task.name,
|
|
144
|
+
type: task.type,
|
|
145
|
+
taskReferenceName: task.taskReferenceName,
|
|
146
|
+
inputParameters: {
|
|
147
|
+
evaluatorType: task.input.evaluatorType,
|
|
148
|
+
expression: task.input.expression
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
if (task.type === WorkflowTaskType.transform) {
|
|
153
|
+
if (task.name === WorkflowCustomTaskName.convert) {
|
|
154
|
+
return SYSTEM_CONVERT_TASK_CONVERTER(task);
|
|
155
|
+
}
|
|
156
|
+
if (task.name === WorkflowCustomTaskName.construct) {
|
|
157
|
+
return SYSTEM_CONSTRUCT_TASK_CONVERTER(task);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (task.type === WorkflowTaskType.simple) {
|
|
161
|
+
if (task.variant === WorkflowCustomTaskName.action) {
|
|
162
|
+
return WORKFLOW_ACTION_TASK_TEMPLATE(
|
|
163
|
+
task.name,
|
|
164
|
+
task.taskReferenceName,
|
|
165
|
+
task.input,
|
|
166
|
+
task.action
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
if (task.variant === WorkflowCustomTaskName.awaitAgent) {
|
|
170
|
+
return SYSTEM_AWAIT_TASK_CONVERTER(task);
|
|
171
|
+
}
|
|
172
|
+
if (task.variant === WorkflowCustomTaskName.notifyAgent) {
|
|
173
|
+
return SYSTEM_NOTIFY_AI_AGENT_TASK_CONVERTER(task);
|
|
174
|
+
}
|
|
175
|
+
if (task.variant === WorkflowCustomTaskName.reasoning) {
|
|
176
|
+
return SYSTEM_REASONING_TASK_CONVERTER(task);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return SYSTEM_JOIN_TASK_CONVERTER(task);
|
|
180
|
+
}
|
|
181
|
+
function buildTasks(ctx, taskCores) {
|
|
182
|
+
const tasks = [];
|
|
183
|
+
for (const taskCore of taskCores) {
|
|
184
|
+
const task = buildTask(ctx, taskCore);
|
|
185
|
+
if (task) {
|
|
186
|
+
tasks.push(task);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return tasks;
|
|
190
|
+
}
|
|
191
|
+
function buildTrigger(ctx, trigger) {
|
|
192
|
+
if (trigger.type === WorkflowTriggerType.webhook) {
|
|
193
|
+
return WORKFLOW_WEBHOOK_TRIGGER_TEMPLATE(trigger.name, trigger.input);
|
|
194
|
+
}
|
|
195
|
+
if (trigger.type === WorkflowTriggerType.webhookManual) {
|
|
196
|
+
return WORKFLOW_SYSTEM_WEBHOOK_TRIGGER_TEMPLATE(trigger.name, trigger);
|
|
197
|
+
}
|
|
198
|
+
if (trigger.type === WorkflowTriggerType.recurring) {
|
|
199
|
+
return WORKFLOW_SCHEDULED_TRIGGER_TEMPLATE(
|
|
200
|
+
SYSTEM_SCHEDULED_TRIGGER_NAME,
|
|
201
|
+
trigger
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
if (trigger.type === WorkflowTriggerType.manual) {
|
|
205
|
+
return WORKFLOW_MANUAL_TRIGGER_TEMPLATE(SYSTEM_MANUAL_TRIGGER_NAME, {
|
|
206
|
+
parameters: trigger.input
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
if (trigger.type === WorkflowTriggerType.agent) {
|
|
210
|
+
return WORKFLOW_AGENT_TRIGGER_TEMPLATE(
|
|
211
|
+
SYSTEM_AI_AGENT_TRIGGER_NAME,
|
|
212
|
+
trigger
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
ctx.errors.push(`Unknown trigger type: ${String(trigger.type)}`);
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
function buildWorkflowFromLight(input, spec) {
|
|
219
|
+
const ctx = {
|
|
220
|
+
spec: spec != null ? spec : getSpecification(),
|
|
221
|
+
errors: [],
|
|
222
|
+
referenceCounters: {}
|
|
223
|
+
};
|
|
224
|
+
const trigger = input.trigger ? buildTrigger(ctx, input.trigger) : null;
|
|
225
|
+
const tasks = buildTasks(ctx, input.tasks);
|
|
226
|
+
return {
|
|
227
|
+
workflow: {
|
|
228
|
+
name: input.name,
|
|
229
|
+
description: input.description,
|
|
230
|
+
trigger,
|
|
231
|
+
definition: {
|
|
232
|
+
name: input.name,
|
|
233
|
+
version: 0,
|
|
234
|
+
tasks,
|
|
235
|
+
inputParameters: []
|
|
236
|
+
}
|
|
237
|
+
},
|
|
238
|
+
errors: ctx.errors
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// src/domain/common/prefill.tsx
|
|
243
|
+
import { cloneDeep as cloneDeep2, get as get2, set as set2 } from "lodash-es";
|
|
244
|
+
import { mergeDeep, WorkflowTaskType as WorkflowTaskType5 } from "@livechat/developer-studio-api";
|
|
245
|
+
|
|
246
|
+
// src/utils/tracking.ts
|
|
247
|
+
import * as amplitude from "@amplitude/analytics-browser";
|
|
248
|
+
|
|
249
|
+
// src/domain/contexts/actions/types.ts
|
|
250
|
+
var WorkflowElementActionType = /* @__PURE__ */ ((WorkflowElementActionType2) => {
|
|
251
|
+
WorkflowElementActionType2["AddTrigger"] = "add_trigger";
|
|
252
|
+
WorkflowElementActionType2["SwitchTrigger"] = "switch_trigger";
|
|
253
|
+
WorkflowElementActionType2["AddToTrigger"] = "add_to_trigger";
|
|
254
|
+
return WorkflowElementActionType2;
|
|
255
|
+
})(WorkflowElementActionType || {});
|
|
256
|
+
|
|
257
|
+
// src/domain/contexts/actions/utils.ts
|
|
258
|
+
import {
|
|
259
|
+
WorkflowTriggerType as WorkflowTriggerType2
|
|
260
|
+
} from "@livechat/developer-studio-api";
|
|
261
|
+
var getWorkflowTaskActions = (config, suggestions, trigger) => {
|
|
262
|
+
var _a;
|
|
263
|
+
const actions = {};
|
|
264
|
+
Object.entries((_a = config.specification.inputReferences) != null ? _a : {}).forEach(
|
|
265
|
+
([referenceName, paths]) => {
|
|
266
|
+
const currentAssetConfig = workflowReferences[referenceName];
|
|
267
|
+
if (!currentAssetConfig || currentAssetConfig.kind !== "resource" /* Resource */) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
paths.forEach((ref) => {
|
|
271
|
+
const path = ref.value;
|
|
272
|
+
const suggestion = suggestions[path];
|
|
273
|
+
const hasSuggestions = suggestion && suggestion.length > 0;
|
|
274
|
+
if (!hasSuggestions) {
|
|
275
|
+
if (!(trigger == null ? void 0 : trigger.data.type)) {
|
|
276
|
+
actions[path] = {
|
|
277
|
+
type: "add_trigger" /* AddTrigger */,
|
|
278
|
+
referenceName
|
|
279
|
+
};
|
|
280
|
+
} else if ([
|
|
281
|
+
WorkflowTriggerType2.manual,
|
|
282
|
+
WorkflowTriggerType2.agent,
|
|
283
|
+
WorkflowTriggerType2.webhookManual
|
|
284
|
+
].includes(trigger.data.type)) {
|
|
285
|
+
actions[path] = {
|
|
286
|
+
type: "add_to_trigger" /* AddToTrigger */,
|
|
287
|
+
referenceName
|
|
288
|
+
};
|
|
289
|
+
} else {
|
|
290
|
+
actions[path] = {
|
|
291
|
+
type: "switch_trigger" /* SwitchTrigger */,
|
|
292
|
+
referenceName
|
|
293
|
+
};
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
);
|
|
299
|
+
return actions;
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
// src/domain/contexts/assets/utils.ts
|
|
303
|
+
function mergeAssets(prevAssets, newAssets) {
|
|
304
|
+
const result = { ...prevAssets };
|
|
305
|
+
Object.entries(newAssets).forEach(([resourceName, newResourceArray]) => {
|
|
306
|
+
if (resourceName in result) {
|
|
307
|
+
const existingResources = result[resourceName];
|
|
308
|
+
const mergedResources = [...existingResources];
|
|
309
|
+
newResourceArray.forEach((newResource) => {
|
|
310
|
+
const isDuplicate = existingResources.some(
|
|
311
|
+
(existing) => existing.reference.taskName === newResource.reference.taskName && existing.reference.ref.value === newResource.reference.ref.value
|
|
312
|
+
);
|
|
313
|
+
if (!isDuplicate) {
|
|
314
|
+
mergedResources.push(newResource);
|
|
315
|
+
} else {
|
|
316
|
+
const index = mergedResources.findIndex(
|
|
317
|
+
(existing) => existing.reference.taskName === newResource.reference.taskName && existing.reference.ref.value === newResource.reference.ref.value
|
|
318
|
+
);
|
|
319
|
+
if (index !== -1) {
|
|
320
|
+
mergedResources[index] = newResource;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
});
|
|
324
|
+
result[resourceName] = mergedResources;
|
|
325
|
+
} else {
|
|
326
|
+
result[resourceName] = [...newResourceArray];
|
|
327
|
+
}
|
|
328
|
+
});
|
|
329
|
+
return result;
|
|
330
|
+
}
|
|
331
|
+
var getTriggerAssets = (trigger, specification) => {
|
|
332
|
+
const assetResources = Object.keys({
|
|
333
|
+
...specification.outputReferences,
|
|
334
|
+
...specification.outputResources
|
|
335
|
+
}).reduce((acc, resourceName) => {
|
|
336
|
+
var _a, _b, _c;
|
|
337
|
+
const outputReferences = (_a = specification.outputReferences) == null ? void 0 : _a[resourceName];
|
|
338
|
+
const outputResources = (_b = specification.outputResources) == null ? void 0 : _b[resourceName];
|
|
339
|
+
const items = (_c = outputReferences == null ? void 0 : outputReferences.map((refItem) => ({
|
|
340
|
+
reference: {
|
|
341
|
+
taskName: "workflow.input",
|
|
342
|
+
ref: refItem
|
|
343
|
+
},
|
|
344
|
+
resource: (outputResources == null ? void 0 : outputResources[0]) ? {
|
|
345
|
+
taskName: "workflow.input",
|
|
346
|
+
ref: outputResources[0]
|
|
347
|
+
} : void 0,
|
|
348
|
+
subject: refItem.subject
|
|
349
|
+
}))) != null ? _c : [];
|
|
350
|
+
if (items.length > 0) {
|
|
351
|
+
acc[resourceName] = items;
|
|
352
|
+
}
|
|
353
|
+
return acc;
|
|
354
|
+
}, {});
|
|
355
|
+
return assetResources;
|
|
356
|
+
};
|
|
357
|
+
var getTaskAssets = (task, specification, prevAssets) => {
|
|
358
|
+
const resources = Object.fromEntries(
|
|
359
|
+
Object.keys({
|
|
360
|
+
...specification.outputReferences,
|
|
361
|
+
...specification.outputResources
|
|
362
|
+
}).map((referenceName) => {
|
|
363
|
+
var _a, _b, _c, _d;
|
|
364
|
+
const existingAssets = prevAssets[referenceName];
|
|
365
|
+
const inputReferences = (_a = specification.inputReferences) == null ? void 0 : _a[referenceName];
|
|
366
|
+
const outputReferences = (_b = specification.outputReferences) == null ? void 0 : _b[referenceName];
|
|
367
|
+
const outputResources = (_c = specification.outputResources) == null ? void 0 : _c[referenceName];
|
|
368
|
+
const newAssetData = (_d = outputReferences == null ? void 0 : outputReferences.map((refItem) => ({
|
|
369
|
+
reference: {
|
|
370
|
+
taskName: task.taskReferenceName,
|
|
371
|
+
ref: refItem
|
|
372
|
+
},
|
|
373
|
+
resource: (outputResources == null ? void 0 : outputResources[0]) ? {
|
|
374
|
+
taskName: "workflow.input",
|
|
375
|
+
ref: outputResources[0]
|
|
376
|
+
} : void 0,
|
|
377
|
+
subject: refItem.subject
|
|
378
|
+
}))) != null ? _d : [];
|
|
379
|
+
const newAsset = [referenceName, newAssetData];
|
|
380
|
+
if (!inputReferences) {
|
|
381
|
+
return newAsset;
|
|
382
|
+
}
|
|
383
|
+
const isEmpty = inputReferences.some((res) => {
|
|
384
|
+
var _a2;
|
|
385
|
+
const value = (_a2 = jsonUtils.extractByPath(res.value, task)) == null ? void 0 : _a2[0];
|
|
386
|
+
if (!value) {
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
return false;
|
|
390
|
+
});
|
|
391
|
+
if (isEmpty) {
|
|
392
|
+
return [
|
|
393
|
+
referenceName,
|
|
394
|
+
newAssetData.map((item) => ({
|
|
395
|
+
...item,
|
|
396
|
+
isNotConfirmed: true
|
|
397
|
+
}))
|
|
398
|
+
];
|
|
399
|
+
}
|
|
400
|
+
const matchedAsset = existingAssets ? existingAssets.find((item) => {
|
|
401
|
+
return inputReferences.some((res) => {
|
|
402
|
+
var _a2;
|
|
403
|
+
const value = (_a2 = jsonUtils.extractByPath(res.value, task)) == null ? void 0 : _a2[0];
|
|
404
|
+
if (!value || typeof value !== "string") {
|
|
405
|
+
return false;
|
|
406
|
+
}
|
|
407
|
+
if (jsonUtils.containsTag(value)) {
|
|
408
|
+
return value.includes(
|
|
409
|
+
`${item.reference.taskName}.${item.reference.ref.value}`
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
return false;
|
|
413
|
+
});
|
|
414
|
+
}) : void 0;
|
|
415
|
+
if (matchedAsset) {
|
|
416
|
+
return [
|
|
417
|
+
referenceName,
|
|
418
|
+
[
|
|
419
|
+
{
|
|
420
|
+
reference: matchedAsset.reference,
|
|
421
|
+
resource: outputResources == null ? void 0 : outputResources[0]
|
|
422
|
+
}
|
|
423
|
+
]
|
|
424
|
+
];
|
|
425
|
+
}
|
|
426
|
+
return newAsset;
|
|
427
|
+
}).filter(([, resources2]) => resources2.length > 0)
|
|
428
|
+
);
|
|
429
|
+
return mergeAssets(prevAssets, resources);
|
|
430
|
+
};
|
|
431
|
+
|
|
432
|
+
// src/domain/contexts/configs/utils.ts
|
|
433
|
+
import { cloneDeep, get, set } from "lodash-es";
|
|
434
|
+
import {
|
|
435
|
+
WorkflowConditionTaskLogic,
|
|
436
|
+
WorkflowConditionTaskOperator,
|
|
437
|
+
WorkflowCustomTaskName as WorkflowCustomTaskName2,
|
|
438
|
+
WorkflowTaskType as WorkflowTaskType2,
|
|
439
|
+
WorkflowTriggerType as WorkflowTriggerType3
|
|
440
|
+
} from "@livechat/developer-studio-api";
|
|
441
|
+
|
|
442
|
+
// src/domain/contexts/frames/utils.ts
|
|
443
|
+
function createFrameReferenceByContext(path, context) {
|
|
444
|
+
return createFrameReferenceByEnvironment(path, context == null ? void 0 : context.environment);
|
|
445
|
+
}
|
|
446
|
+
function createFrameReferenceByEnvironment(path, environment) {
|
|
447
|
+
const segments = path.split(".");
|
|
448
|
+
const frame = environment ? segments[0] === "workflow" ? segments[1] === "input" ? environment.workflow.input : void 0 : environment[segments[0]] : void 0;
|
|
449
|
+
return createFrameReference(path, frame);
|
|
450
|
+
}
|
|
451
|
+
var createFrameReference = (path, frame, options) => {
|
|
452
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s;
|
|
453
|
+
const segments = path.split(".");
|
|
454
|
+
let relativePath = (frame == null ? void 0 : frame.__meta) ? path.replaceAll(frame.__meta.basePath, "") : null;
|
|
455
|
+
relativePath = relativePath && relativePath.startsWith(".") ? relativePath.slice(1) : relativePath;
|
|
456
|
+
const contentRelativePath = relativePath && (frame == null ? void 0 : frame.__meta) ? relativePath.replaceAll(`${frame.__meta.contentBasePath}.`, "") : null;
|
|
457
|
+
const meta = frame == null ? void 0 : frame.__meta;
|
|
458
|
+
const { customization, specification } = (_b = (_a = meta == null ? void 0 : meta.config) != null ? _a : getWorkflowSpecificationItemByReference(path)) != null ? _b : {};
|
|
459
|
+
const arrayItemReferenceMatch = contentRelativePath ? /\[(\d+)\]$/.exec(contentRelativePath) : null;
|
|
460
|
+
const arrayItemIndex = (arrayItemReferenceMatch == null ? void 0 : arrayItemReferenceMatch[1]) ? parseInt(arrayItemReferenceMatch[1], 10) : void 0;
|
|
461
|
+
const { resolvedSchema: schema } = relativePath ? validatePathAgainstSchema(relativePath, specification == null ? void 0 : specification.output, {
|
|
462
|
+
supportAdditionalItems: options == null ? void 0 : options.supportAdditionalItems
|
|
463
|
+
}) : { resolvedSchema: void 0 };
|
|
464
|
+
const isArray = (schema == null ? void 0 : schema.type) === "array";
|
|
465
|
+
const isArrayReference = isArray && arrayItemIndex !== void 0;
|
|
466
|
+
const { value: reference } = (_c = schema ? getWorkflowReferenceDefinitionFromSchema(schema, arrayItemIndex) : void 0) != null ? _c : {};
|
|
467
|
+
const data = schema ? reference ? {
|
|
468
|
+
title: [
|
|
469
|
+
(_e = (_d = schema.title) != null ? _d : reference.title) != null ? _e : reference.displayName,
|
|
470
|
+
isArrayReference ? `[${arrayItemIndex}]` : ""
|
|
471
|
+
].filter(notEmpty).join(""),
|
|
472
|
+
displayName: isArray ? isArrayReference ? `${schema.title}[${arrayItemIndex}]` : (_f = schema.title) != null ? _f : reference.pluralDisplayName : reference.displayName,
|
|
473
|
+
type: isArray ? isArrayReference ? reference.type : "array" : reference.type,
|
|
474
|
+
displayType: isArray ? isArrayReference ? reference.displayName : reference.pluralDisplayName : reference.displayName,
|
|
475
|
+
description: reference.description,
|
|
476
|
+
example: (_g = reference.examples) == null ? void 0 : _g[0]
|
|
477
|
+
} : {
|
|
478
|
+
title: (_i = (_h = schema.title) != null ? _h : segments.at(-1)) != null ? _i : "",
|
|
479
|
+
displayName: (_k = (_j = schema.title) != null ? _j : segments.at(-1)) != null ? _k : "",
|
|
480
|
+
type: schema.type,
|
|
481
|
+
displayType: resolveDisplayType(schema),
|
|
482
|
+
description: schema.description,
|
|
483
|
+
example: (_l = schema.examples) == null ? void 0 : _l[0]
|
|
484
|
+
} : {
|
|
485
|
+
title: (_n = (_m = customization == null ? void 0 : customization.displayName) != null ? _m : segments.at(-1)) != null ? _n : "",
|
|
486
|
+
displayName: (_p = (_o = customization == null ? void 0 : customization.displayName) != null ? _o : segments.at(-1)) != null ? _p : ""
|
|
487
|
+
};
|
|
488
|
+
let invalid = false;
|
|
489
|
+
let invalidReason = "";
|
|
490
|
+
let invalidLevel;
|
|
491
|
+
if (meta) {
|
|
492
|
+
if (!schema) {
|
|
493
|
+
invalid = true;
|
|
494
|
+
invalidLevel = "error";
|
|
495
|
+
invalidReason = segments[0] === "workflow" ? "Invalid trigger property" : "Invalid task property";
|
|
496
|
+
} else if (meta.config.stale) {
|
|
497
|
+
invalid = true;
|
|
498
|
+
invalidLevel = "warning";
|
|
499
|
+
invalidReason = segments[0] === "workflow" ? "Stale trigger property" : "Stale task property";
|
|
500
|
+
}
|
|
501
|
+
} else {
|
|
502
|
+
invalid = true;
|
|
503
|
+
invalidLevel = "error";
|
|
504
|
+
invalidReason = `${segments[0] === "workflow" ? "Trigger" : "Task"} not found`;
|
|
505
|
+
}
|
|
506
|
+
const outcome = relativePath ? (_q = jsonUtils.extractByPath(relativePath, frame)) == null ? void 0 : _q[0] : null;
|
|
507
|
+
const tag = {
|
|
508
|
+
// Paths
|
|
509
|
+
value: path,
|
|
510
|
+
targetValue: `\${${path}}`,
|
|
511
|
+
relativePath: contentRelativePath,
|
|
512
|
+
path: relativePath,
|
|
513
|
+
// Display
|
|
514
|
+
name: data.title,
|
|
515
|
+
displayName: data.displayName,
|
|
516
|
+
type: (_r = data.type) != null ? _r : "",
|
|
517
|
+
displayType: (_s = data.displayType) != null ? _s : "",
|
|
518
|
+
description: data.description,
|
|
519
|
+
example: data.example,
|
|
520
|
+
// Output
|
|
521
|
+
outcome,
|
|
522
|
+
// Schema
|
|
523
|
+
schema,
|
|
524
|
+
reference,
|
|
525
|
+
// Validation
|
|
526
|
+
invalid,
|
|
527
|
+
invalidReason,
|
|
528
|
+
invalidLevel,
|
|
529
|
+
// Source
|
|
530
|
+
source: {
|
|
531
|
+
index: meta == null ? void 0 : meta.index,
|
|
532
|
+
reference: frame == null ? void 0 : frame.__meta.basePath,
|
|
533
|
+
credentialId: frame == null ? void 0 : frame.__meta.credentialId,
|
|
534
|
+
customization
|
|
535
|
+
}
|
|
536
|
+
};
|
|
537
|
+
return tag;
|
|
538
|
+
};
|
|
539
|
+
|
|
540
|
+
// src/domain/contexts/configs/utils.ts
|
|
541
|
+
function getWorkflowElementVersion(element) {
|
|
542
|
+
var _a;
|
|
543
|
+
if (element.type === WorkflowTriggerType3.webhook) {
|
|
544
|
+
return (_a = element.webhook.event.version) != null ? _a : element.version;
|
|
545
|
+
}
|
|
546
|
+
return element.version;
|
|
547
|
+
}
|
|
548
|
+
function getWorkflowElementConfig(elementData, workflowIntrospection, specification, environment) {
|
|
549
|
+
var _a, _b;
|
|
550
|
+
const itemConfig = specification.raw.items[elementData.name];
|
|
551
|
+
if (!itemConfig) {
|
|
552
|
+
throw new Error(
|
|
553
|
+
"Invalid workflow element - no config found for element with name: " + elementData.name
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
const itemProviderConfig = specification.raw.providers[itemConfig.customization.provider];
|
|
557
|
+
const itemProductConfig = itemConfig.customization.product ? (_a = itemProviderConfig.products) == null ? void 0 : _a[itemConfig.customization.product] : void 0;
|
|
558
|
+
const itemVersion = (_b = getWorkflowElementVersion(elementData)) != null ? _b : itemConfig.specifications.default;
|
|
559
|
+
let itemSpecification = itemConfig.specifications.versions[itemVersion];
|
|
560
|
+
if (itemSpecification && elementData.type === WorkflowTaskType2.http && elementData.name === WorkflowTaskType2.http) {
|
|
561
|
+
itemSpecification = {
|
|
562
|
+
...itemSpecification,
|
|
563
|
+
...adjustSpecificationForHttpTask(elementData, workflowIntrospection)
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
if (itemSpecification && elementData.name === WorkflowCustomTaskName2.convert) {
|
|
567
|
+
itemSpecification = {
|
|
568
|
+
...itemSpecification,
|
|
569
|
+
...adjustSpecificationForConvertTask(
|
|
570
|
+
elementData,
|
|
571
|
+
itemSpecification,
|
|
572
|
+
environment
|
|
573
|
+
)
|
|
574
|
+
};
|
|
575
|
+
}
|
|
576
|
+
if (itemSpecification && elementData.name === WorkflowCustomTaskName2.construct) {
|
|
577
|
+
itemSpecification = {
|
|
578
|
+
...itemSpecification,
|
|
579
|
+
...adjustSpecificationForConstructTask(
|
|
580
|
+
elementData,
|
|
581
|
+
itemSpecification,
|
|
582
|
+
environment
|
|
583
|
+
)
|
|
584
|
+
};
|
|
585
|
+
}
|
|
586
|
+
if (itemSpecification) {
|
|
587
|
+
itemSpecification = {
|
|
588
|
+
...itemSpecification,
|
|
589
|
+
...adjustOutputSchemaFromBindings(elementData, itemSpecification)
|
|
590
|
+
};
|
|
591
|
+
}
|
|
592
|
+
const config = {
|
|
593
|
+
...itemConfig,
|
|
594
|
+
customization: {
|
|
595
|
+
...itemConfig.customization,
|
|
596
|
+
providerDisplay: itemProviderConfig.displayName,
|
|
597
|
+
productDisplay: itemProductConfig == null ? void 0 : itemProductConfig.displayName
|
|
598
|
+
},
|
|
599
|
+
specification: itemSpecification
|
|
600
|
+
};
|
|
601
|
+
return config;
|
|
602
|
+
}
|
|
603
|
+
function adjustSpecificationForHttpTask(taskData, workflowIntrospection) {
|
|
604
|
+
const taskIntrospection = workflowIntrospection.tasks[taskData.taskReferenceName];
|
|
605
|
+
if (!(taskIntrospection == null ? void 0 : taskIntrospection.schema)) {
|
|
606
|
+
return {};
|
|
607
|
+
}
|
|
608
|
+
const output = WORKFLOW_HTTP_TASK_OUTPUT_SCHEMA(
|
|
609
|
+
taskIntrospection.schema
|
|
610
|
+
);
|
|
611
|
+
return { output };
|
|
612
|
+
}
|
|
613
|
+
function resolveBindingReferences(properties) {
|
|
614
|
+
return Object.fromEntries(
|
|
615
|
+
Object.entries(properties).filter((entry) => Boolean(entry[1])).map(([key, schema]) => {
|
|
616
|
+
var _a;
|
|
617
|
+
const type = typeof schema.type === "string" ? schema.type : void 0;
|
|
618
|
+
if (type == null ? void 0 : type.startsWith("references/")) {
|
|
619
|
+
const name = type.slice("references/".length);
|
|
620
|
+
const definition = getWorkflowReferenceDefinitionByName(name);
|
|
621
|
+
if (definition) {
|
|
622
|
+
return [
|
|
623
|
+
key,
|
|
624
|
+
{
|
|
625
|
+
...definition,
|
|
626
|
+
title: (_a = schema.title) != null ? _a : definition.title,
|
|
627
|
+
$ref: getWorkflowReferenceDefRef(name)
|
|
628
|
+
}
|
|
629
|
+
];
|
|
630
|
+
}
|
|
631
|
+
}
|
|
632
|
+
return [key, schema];
|
|
633
|
+
})
|
|
634
|
+
);
|
|
635
|
+
}
|
|
636
|
+
function narrowSchemaByConditions(itemsSchema, filterConditions, filterLogic) {
|
|
637
|
+
var _a, _b, _c;
|
|
638
|
+
if (!itemsSchema.oneOf || !Array.isArray(itemsSchema.oneOf) || !(filterConditions == null ? void 0 : filterConditions.length) || filterLogic === WorkflowConditionTaskLogic.OR) {
|
|
639
|
+
return itemsSchema;
|
|
640
|
+
}
|
|
641
|
+
const equalityOperators = /* @__PURE__ */ new Set([
|
|
642
|
+
WorkflowConditionTaskOperator.StringEqual,
|
|
643
|
+
WorkflowConditionTaskOperator.NumberEqual
|
|
644
|
+
]);
|
|
645
|
+
const equalityConditions = filterConditions.filter(
|
|
646
|
+
(c) => c.field && c.value !== void 0 && equalityOperators.has(c.operator)
|
|
647
|
+
);
|
|
648
|
+
if (!equalityConditions.length) {
|
|
649
|
+
return itemsSchema;
|
|
650
|
+
}
|
|
651
|
+
const variants = itemsSchema.oneOf;
|
|
652
|
+
for (const condition of equalityConditions) {
|
|
653
|
+
const matchingVariant = variants.find((variant) => {
|
|
654
|
+
const variantProps = variant.properties;
|
|
655
|
+
if (!(variantProps == null ? void 0 : variantProps[condition.field])) return false;
|
|
656
|
+
return variantProps[condition.field].const === condition.value;
|
|
657
|
+
});
|
|
658
|
+
if (matchingVariant) {
|
|
659
|
+
const { oneOf: _, ...baseSchema } = itemsSchema;
|
|
660
|
+
const variantProps = (_a = matchingVariant.properties) != null ? _a : {};
|
|
661
|
+
const variantRequired = (_b = matchingVariant.required) != null ? _b : [];
|
|
662
|
+
return {
|
|
663
|
+
...baseSchema,
|
|
664
|
+
properties: {
|
|
665
|
+
...baseSchema.properties,
|
|
666
|
+
...variantProps
|
|
667
|
+
},
|
|
668
|
+
required: [
|
|
669
|
+
.../* @__PURE__ */ new Set([
|
|
670
|
+
...(_c = baseSchema.required) != null ? _c : [],
|
|
671
|
+
...variantRequired
|
|
672
|
+
])
|
|
673
|
+
]
|
|
674
|
+
};
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
return itemsSchema;
|
|
678
|
+
}
|
|
679
|
+
function deriveOutputSchemaFromTransformer(taskData, sourceSchema) {
|
|
680
|
+
var _a, _b;
|
|
681
|
+
const transformer = taskData.inputParameters.transformer;
|
|
682
|
+
const sourceItemsSchema = (sourceSchema == null ? void 0 : sourceSchema.type) === "array" && sourceSchema.items ? Array.isArray(sourceSchema.items) ? sourceSchema.items[0] : sourceSchema.items : void 0;
|
|
683
|
+
switch (transformer) {
|
|
684
|
+
// → string
|
|
685
|
+
case "to_string":
|
|
686
|
+
case "uppercase":
|
|
687
|
+
case "lowercase":
|
|
688
|
+
case "trim":
|
|
689
|
+
case "replace":
|
|
690
|
+
case "join":
|
|
691
|
+
return { type: "string" };
|
|
692
|
+
// → number
|
|
693
|
+
case "to_number":
|
|
694
|
+
case "count":
|
|
695
|
+
case "sum":
|
|
696
|
+
case "average":
|
|
697
|
+
return { type: "number" };
|
|
698
|
+
// → array of strings
|
|
699
|
+
case "split":
|
|
700
|
+
case "keys":
|
|
701
|
+
return { type: "array", items: { type: "string" } };
|
|
702
|
+
// → array (preserves item schema, narrows discriminated unions)
|
|
703
|
+
case "filter": {
|
|
704
|
+
if (!sourceItemsSchema) return { type: "array" };
|
|
705
|
+
const narrowed = narrowSchemaByConditions(
|
|
706
|
+
sourceItemsSchema,
|
|
707
|
+
taskData.inputParameters.filterConditions,
|
|
708
|
+
taskData.inputParameters.filterLogic
|
|
709
|
+
);
|
|
710
|
+
return { type: "array", items: narrowed };
|
|
711
|
+
}
|
|
712
|
+
// → array (preserves item schema)
|
|
713
|
+
case "sort":
|
|
714
|
+
case "reverse":
|
|
715
|
+
case "unique":
|
|
716
|
+
return sourceItemsSchema ? { type: "array", items: sourceItemsSchema } : { type: "array" };
|
|
717
|
+
// → array (unknown items)
|
|
718
|
+
case "values":
|
|
719
|
+
case "flatten":
|
|
720
|
+
return { type: "array" };
|
|
721
|
+
// → array of plucked field values
|
|
722
|
+
case "pluck": {
|
|
723
|
+
if ((sourceItemsSchema == null ? void 0 : sourceItemsSchema.properties) && taskData.inputParameters.pluckField) {
|
|
724
|
+
const fieldSchema = sourceItemsSchema.properties[taskData.inputParameters.pluckField];
|
|
725
|
+
if (fieldSchema) {
|
|
726
|
+
return { type: "array", items: fieldSchema };
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
return { type: "array" };
|
|
730
|
+
}
|
|
731
|
+
// → single item from array
|
|
732
|
+
case "first":
|
|
733
|
+
case "last":
|
|
734
|
+
return sourceItemsSchema != null ? sourceItemsSchema : {};
|
|
735
|
+
// → object (subset of source)
|
|
736
|
+
case "pick":
|
|
737
|
+
case "omit": {
|
|
738
|
+
if ((sourceSchema == null ? void 0 : sourceSchema.type) === "object" && sourceSchema.properties) {
|
|
739
|
+
const targetFields = (_a = taskData.inputParameters.targetFields) != null ? _a : [];
|
|
740
|
+
if (transformer === "pick") {
|
|
741
|
+
return {
|
|
742
|
+
type: "object",
|
|
743
|
+
properties: Object.fromEntries(
|
|
744
|
+
targetFields.filter((f) => f in sourceSchema.properties).map((f) => [f, sourceSchema.properties[f]])
|
|
745
|
+
)
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
return {
|
|
749
|
+
type: "object",
|
|
750
|
+
properties: Object.fromEntries(
|
|
751
|
+
Object.entries(sourceSchema.properties).filter(
|
|
752
|
+
([key]) => !targetFields.includes(key)
|
|
753
|
+
)
|
|
754
|
+
)
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
return {
|
|
758
|
+
type: "object",
|
|
759
|
+
properties: Object.fromEntries(
|
|
760
|
+
((_b = taskData.inputParameters.targetFields) != null ? _b : []).map((f) => [f, {}])
|
|
761
|
+
)
|
|
762
|
+
};
|
|
763
|
+
}
|
|
764
|
+
// pass-through
|
|
765
|
+
case "none":
|
|
766
|
+
return sourceSchema != null ? sourceSchema : {};
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
function adjustSpecificationForConvertTask(taskData, itemSpecification, environment) {
|
|
770
|
+
const sourceSchema = resolveRefSchema(
|
|
771
|
+
taskData.inputParameters.source,
|
|
772
|
+
environment
|
|
773
|
+
);
|
|
774
|
+
const resultSchema = deriveOutputSchemaFromTransformer(
|
|
775
|
+
taskData,
|
|
776
|
+
sourceSchema
|
|
777
|
+
);
|
|
778
|
+
const taskOutputSchema = {
|
|
779
|
+
type: "object",
|
|
780
|
+
required: ["output"],
|
|
781
|
+
properties: {
|
|
782
|
+
output: {
|
|
783
|
+
type: "object",
|
|
784
|
+
required: ["result"],
|
|
785
|
+
properties: {
|
|
786
|
+
result: {
|
|
787
|
+
title: "Result",
|
|
788
|
+
...resultSchema
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
}
|
|
793
|
+
};
|
|
794
|
+
const { references: taskOutputReferences, resources: taskOutputResources } = collectSchemaRefs(taskOutputSchema, false);
|
|
795
|
+
const inputAdjustment = adjustConvertConditionInputSchema(
|
|
796
|
+
itemSpecification,
|
|
797
|
+
sourceSchema
|
|
798
|
+
);
|
|
799
|
+
return {
|
|
800
|
+
output: taskOutputSchema,
|
|
801
|
+
outputReferences: taskOutputReferences,
|
|
802
|
+
outputResources: taskOutputResources,
|
|
803
|
+
...inputAdjustment != null ? inputAdjustment : {}
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
function adjustConvertConditionInputSchema(itemSpecification, sourceSchema) {
|
|
807
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
808
|
+
if (!itemSpecification.input) return void 0;
|
|
809
|
+
if (sourceSchema.type !== "array") return void 0;
|
|
810
|
+
const itemsSchema = Array.isArray(sourceSchema.items) ? sourceSchema.items[0] : sourceSchema.items;
|
|
811
|
+
if (!itemsSchema) return void 0;
|
|
812
|
+
const itemType = typeof itemsSchema.type === "string" ? itemsSchema.type : void 0;
|
|
813
|
+
if (!itemType) return void 0;
|
|
814
|
+
const isPrimitive = itemType === "string" || itemType === "number" || itemType === "integer" || itemType === "boolean";
|
|
815
|
+
let fieldPatch;
|
|
816
|
+
let fieldUiPatch;
|
|
817
|
+
let operatorPatch;
|
|
818
|
+
if (isPrimitive) {
|
|
819
|
+
fieldPatch = { type: "string", title: "Field", default: "" };
|
|
820
|
+
fieldUiPatch = { "ui:widget": "hidden" };
|
|
821
|
+
operatorPatch = {
|
|
822
|
+
type: "string",
|
|
823
|
+
title: "Type",
|
|
824
|
+
oneOf: getConditionOperatorsForType(itemType)
|
|
825
|
+
};
|
|
826
|
+
} else if (itemType === "object" && itemsSchema.properties) {
|
|
827
|
+
const props = itemsSchema.properties;
|
|
828
|
+
const fieldKeys = Object.keys(props);
|
|
829
|
+
if (!fieldKeys.length) return void 0;
|
|
830
|
+
fieldPatch = {
|
|
831
|
+
type: "string",
|
|
832
|
+
title: "Field",
|
|
833
|
+
oneOf: fieldKeys.map(
|
|
834
|
+
(k) => {
|
|
835
|
+
var _a2;
|
|
836
|
+
return {
|
|
837
|
+
const: k,
|
|
838
|
+
title: (_a2 = props[k].title) != null ? _a2 : k
|
|
839
|
+
};
|
|
840
|
+
}
|
|
841
|
+
)
|
|
842
|
+
};
|
|
843
|
+
} else {
|
|
844
|
+
return void 0;
|
|
845
|
+
}
|
|
846
|
+
const newInput = cloneDeep(itemSpecification.input);
|
|
847
|
+
const newInputUi = cloneDeep((_a = itemSpecification.inputUi) != null ? _a : {});
|
|
848
|
+
const inputProps = (_b = newInput.properties) != null ? _b : {};
|
|
849
|
+
const inputParams = inputProps.inputParameters;
|
|
850
|
+
const allOf = (_c = inputParams == null ? void 0 : inputParams.allOf) != null ? _c : [];
|
|
851
|
+
let patched = false;
|
|
852
|
+
for (const branch of allOf) {
|
|
853
|
+
const then = branch.then;
|
|
854
|
+
const thenProps = then == null ? void 0 : then.properties;
|
|
855
|
+
const fc = thenProps == null ? void 0 : thenProps.filterConditions;
|
|
856
|
+
if (!fc) continue;
|
|
857
|
+
const items = fc.items;
|
|
858
|
+
if (!items) continue;
|
|
859
|
+
const itemProps = (_d = items.properties) != null ? _d : {};
|
|
860
|
+
if (fieldPatch) itemProps.field = fieldPatch;
|
|
861
|
+
if (operatorPatch) itemProps.operator = operatorPatch;
|
|
862
|
+
items.properties = itemProps;
|
|
863
|
+
patched = true;
|
|
864
|
+
}
|
|
865
|
+
if (!patched) return void 0;
|
|
866
|
+
if (fieldUiPatch) {
|
|
867
|
+
const inputParamsUi = (_e = newInputUi.inputParameters) != null ? _e : {};
|
|
868
|
+
const fcUi = (_f = inputParamsUi.filterConditions) != null ? _f : {};
|
|
869
|
+
const fcItemsUi = (_g = fcUi.items) != null ? _g : {};
|
|
870
|
+
fcItemsUi.field = { ...(_h = fcItemsUi.field) != null ? _h : {}, ...fieldUiPatch };
|
|
871
|
+
fcUi.items = fcItemsUi;
|
|
872
|
+
inputParamsUi.filterConditions = fcUi;
|
|
873
|
+
newInputUi.inputParameters = inputParamsUi;
|
|
874
|
+
}
|
|
875
|
+
return { input: newInput, inputUi: newInputUi };
|
|
876
|
+
}
|
|
877
|
+
function resolveRefSchema(value, environment) {
|
|
878
|
+
var _a;
|
|
879
|
+
if (!value || !environment || !jsonUtils.containsTag(value)) return {};
|
|
880
|
+
const path = jsonUtils.escapeTag(value);
|
|
881
|
+
const ref = createFrameReferenceByEnvironment(path, environment);
|
|
882
|
+
return (_a = ref.schema) != null ? _a : {};
|
|
883
|
+
}
|
|
884
|
+
function adjustSpecificationForConstructTask(taskData, itemSpecification, environment) {
|
|
885
|
+
var _a, _b;
|
|
886
|
+
let resultSchema;
|
|
887
|
+
const keysFrom = taskData.inputParameters.keysFrom;
|
|
888
|
+
const valuesFrom = taskData.inputParameters.valuesFrom;
|
|
889
|
+
const valuesReferenceSchema = valuesFrom ? {
|
|
890
|
+
...getWorkflowReferenceDefinitionByName(valuesFrom),
|
|
891
|
+
$ref: getWorkflowReferenceDefRef(valuesFrom)
|
|
892
|
+
} : void 0;
|
|
893
|
+
if (taskData.inputParameters.outputType === "object") {
|
|
894
|
+
const fields = (_a = taskData.inputParameters.fields) != null ? _a : [];
|
|
895
|
+
resultSchema = {
|
|
896
|
+
type: "object",
|
|
897
|
+
properties: Object.fromEntries(
|
|
898
|
+
fields.map((f) => [
|
|
899
|
+
f.key,
|
|
900
|
+
valuesReferenceSchema ? { ...valuesReferenceSchema, title: f.key } : { ...resolveRefSchema(f.value, environment), title: f.key }
|
|
901
|
+
])
|
|
902
|
+
)
|
|
903
|
+
};
|
|
904
|
+
} else {
|
|
905
|
+
const elements = (_b = taskData.inputParameters.elements) != null ? _b : [];
|
|
906
|
+
let itemsSchema;
|
|
907
|
+
if (valuesReferenceSchema) {
|
|
908
|
+
itemsSchema = valuesReferenceSchema;
|
|
909
|
+
} else {
|
|
910
|
+
const itemSchemas = elements.map(
|
|
911
|
+
(e) => resolveRefSchema(e.value, environment)
|
|
912
|
+
);
|
|
913
|
+
itemsSchema = itemSchemas.length === 1 ? itemSchemas[0] : itemSchemas.length > 1 ? { oneOf: itemSchemas } : {};
|
|
914
|
+
}
|
|
915
|
+
resultSchema = { type: "array", items: itemsSchema };
|
|
916
|
+
}
|
|
917
|
+
if (keysFrom) {
|
|
918
|
+
resultSchema["x-keys-reference"] = keysFrom;
|
|
919
|
+
}
|
|
920
|
+
if (valuesFrom) {
|
|
921
|
+
resultSchema["x-values-reference"] = valuesFrom;
|
|
922
|
+
}
|
|
923
|
+
const taskOutputSchema = {
|
|
924
|
+
type: "object",
|
|
925
|
+
required: ["output"],
|
|
926
|
+
properties: {
|
|
927
|
+
output: {
|
|
928
|
+
type: "object",
|
|
929
|
+
required: ["result"],
|
|
930
|
+
properties: {
|
|
931
|
+
result: resultSchema
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
const { references: taskOutputReferences, resources: taskOutputResources } = collectSchemaRefs(taskOutputSchema, false);
|
|
937
|
+
const inputAdjustment = adjustConstructEntriesReferenceSchema(
|
|
938
|
+
taskData,
|
|
939
|
+
itemSpecification
|
|
940
|
+
);
|
|
941
|
+
return {
|
|
942
|
+
output: taskOutputSchema,
|
|
943
|
+
outputReferences: taskOutputReferences,
|
|
944
|
+
outputResources: taskOutputResources,
|
|
945
|
+
...inputAdjustment != null ? inputAdjustment : {}
|
|
946
|
+
};
|
|
947
|
+
}
|
|
948
|
+
function adjustConstructEntriesReferenceSchema(taskData, itemSpecification) {
|
|
949
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
950
|
+
if (!itemSpecification.input) return void 0;
|
|
951
|
+
const isObject = taskData.inputParameters.outputType === "object";
|
|
952
|
+
const keysFrom = taskData.inputParameters.keysFrom;
|
|
953
|
+
const valuesFrom = taskData.inputParameters.valuesFrom;
|
|
954
|
+
const branchKey = isObject ? "fields" : "elements";
|
|
955
|
+
const slotPatches = [];
|
|
956
|
+
if (isObject && keysFrom)
|
|
957
|
+
slotPatches.push({ slot: "key", refName: keysFrom });
|
|
958
|
+
if (valuesFrom) slotPatches.push({ slot: "value", refName: valuesFrom });
|
|
959
|
+
if (!slotPatches.length) return void 0;
|
|
960
|
+
const resolvedRefs = slotPatches.map((p) => ({
|
|
961
|
+
...p,
|
|
962
|
+
definition: getWorkflowReferenceDefinitionByName(p.refName)
|
|
963
|
+
}));
|
|
964
|
+
if (resolvedRefs.some((r) => !r.definition)) return void 0;
|
|
965
|
+
const newInput = cloneDeep(itemSpecification.input);
|
|
966
|
+
const newInputUi = cloneDeep((_a = itemSpecification.inputUi) != null ? _a : {});
|
|
967
|
+
const inputProps = (_b = newInput.properties) != null ? _b : {};
|
|
968
|
+
const inputParams = inputProps.inputParameters;
|
|
969
|
+
const allOf = (_c = inputParams == null ? void 0 : inputParams.allOf) != null ? _c : [];
|
|
970
|
+
let patched = false;
|
|
971
|
+
for (const branch of allOf) {
|
|
972
|
+
const then = branch.then;
|
|
973
|
+
const thenProps = then == null ? void 0 : then.properties;
|
|
974
|
+
const container = thenProps == null ? void 0 : thenProps[branchKey];
|
|
975
|
+
if (!container) continue;
|
|
976
|
+
const cloned = cloneDeep(container);
|
|
977
|
+
const items = cloned.items;
|
|
978
|
+
const itemProps = (_d = items == null ? void 0 : items.properties) != null ? _d : {};
|
|
979
|
+
for (const { slot, refName, definition } of resolvedRefs) {
|
|
980
|
+
itemProps[slot] = {
|
|
981
|
+
...definition,
|
|
982
|
+
title: slot === "key" ? "Key" : "Value",
|
|
983
|
+
$ref: getWorkflowReferenceDefRef(refName)
|
|
984
|
+
};
|
|
985
|
+
}
|
|
986
|
+
if (items) items.properties = itemProps;
|
|
987
|
+
thenProps[branchKey] = cloned;
|
|
988
|
+
patched = true;
|
|
989
|
+
}
|
|
990
|
+
if (!patched) return void 0;
|
|
991
|
+
const inputParamsUi = (_e = newInputUi.inputParameters) != null ? _e : {};
|
|
992
|
+
const containerUi = (_f = inputParamsUi[branchKey]) != null ? _f : {};
|
|
993
|
+
const containerItemsUi = (_g = containerUi.items) != null ? _g : {};
|
|
994
|
+
for (const { slot, definition } of resolvedRefs) {
|
|
995
|
+
const slotUi = (_h = containerItemsUi[slot]) != null ? _h : {};
|
|
996
|
+
delete slotUi["ui:inputType"];
|
|
997
|
+
slotUi["ui:widget"] = "select";
|
|
998
|
+
slotUi["ui:placeholder"] = `Select ${definition.displayName}`;
|
|
999
|
+
containerItemsUi[slot] = slotUi;
|
|
1000
|
+
}
|
|
1001
|
+
containerUi.items = containerItemsUi;
|
|
1002
|
+
inputParamsUi[branchKey] = containerUi;
|
|
1003
|
+
newInputUi.inputParameters = inputParamsUi;
|
|
1004
|
+
const { references: inputReferences, resources: inputResources } = collectSchemaRefs(newInput, false);
|
|
1005
|
+
return {
|
|
1006
|
+
input: newInput,
|
|
1007
|
+
inputUi: newInputUi,
|
|
1008
|
+
inputReferences,
|
|
1009
|
+
inputResources
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
function getBindingProperties(elementData, inputPath, format) {
|
|
1013
|
+
var _a;
|
|
1014
|
+
const rawData = get(elementData, inputPath);
|
|
1015
|
+
if (!rawData) return {};
|
|
1016
|
+
let properties;
|
|
1017
|
+
if (format === "params-array") {
|
|
1018
|
+
const params = rawData != null ? rawData : [];
|
|
1019
|
+
properties = Object.fromEntries(
|
|
1020
|
+
params.map((param) => [
|
|
1021
|
+
param.name,
|
|
1022
|
+
{
|
|
1023
|
+
title: capitalizeFirstLetter(param.name || ""),
|
|
1024
|
+
type: param.type
|
|
1025
|
+
}
|
|
1026
|
+
])
|
|
1027
|
+
);
|
|
1028
|
+
} else {
|
|
1029
|
+
properties = (_a = rawData.properties) != null ? _a : {};
|
|
1030
|
+
}
|
|
1031
|
+
return resolveBindingReferences(properties);
|
|
1032
|
+
}
|
|
1033
|
+
function buildBindingPropertyUiSchema(schema) {
|
|
1034
|
+
var _a;
|
|
1035
|
+
const ref = getWorkflowReferenceDefinitionFromSchema(schema);
|
|
1036
|
+
if (ref) {
|
|
1037
|
+
const isExternal = (_a = ref.value.configs) == null ? void 0 : _a.external;
|
|
1038
|
+
return {
|
|
1039
|
+
"ui:widget": isExternal ? "select" : void 0,
|
|
1040
|
+
"ui:inputType": isExternal ? void 0 : "static",
|
|
1041
|
+
"ui:placeholder": isExternal ? `Select ${ref.value.displayName}` : `Enter ${ref.value.displayName}`
|
|
1042
|
+
};
|
|
1043
|
+
}
|
|
1044
|
+
if (schema.type === "boolean") {
|
|
1045
|
+
return { "ui:widget": "select" };
|
|
1046
|
+
}
|
|
1047
|
+
}
|
|
1048
|
+
function adjustOutputSchemaFromBindings(elementData, itemSpecification) {
|
|
1049
|
+
var _a;
|
|
1050
|
+
const {
|
|
1051
|
+
output: currentOutput,
|
|
1052
|
+
outputUi: currentOutputUi,
|
|
1053
|
+
outputBindings: bindings
|
|
1054
|
+
} = itemSpecification;
|
|
1055
|
+
if (!currentOutput || !(bindings == null ? void 0 : bindings.length)) return void 0;
|
|
1056
|
+
const output = cloneDeep(currentOutput);
|
|
1057
|
+
const outputUi = currentOutputUi ? cloneDeep(currentOutputUi) : {};
|
|
1058
|
+
for (const binding of bindings) {
|
|
1059
|
+
const bindingSchemaPath = toSchemaPropertiesPath(binding.outputPath);
|
|
1060
|
+
const bindingProperties = getBindingProperties(
|
|
1061
|
+
elementData,
|
|
1062
|
+
binding.inputPath,
|
|
1063
|
+
binding.inputFormat
|
|
1064
|
+
);
|
|
1065
|
+
const node = binding.outputPath ? get(output, bindingSchemaPath) : output;
|
|
1066
|
+
if (!node) continue;
|
|
1067
|
+
node.properties = { ...node.properties, ...bindingProperties };
|
|
1068
|
+
node.required = [
|
|
1069
|
+
.../* @__PURE__ */ new Set([
|
|
1070
|
+
...Array.isArray(node.required) ? node.required : [],
|
|
1071
|
+
...Object.keys(bindingProperties)
|
|
1072
|
+
])
|
|
1073
|
+
];
|
|
1074
|
+
node.additionalProperties = false;
|
|
1075
|
+
node.additionalItems = true;
|
|
1076
|
+
const nodeUi = Object.fromEntries(
|
|
1077
|
+
Object.entries(bindingProperties).map(
|
|
1078
|
+
([key, schema]) => [key, buildBindingPropertyUiSchema(schema)]
|
|
1079
|
+
).filter((entry) => Boolean(entry[1]))
|
|
1080
|
+
);
|
|
1081
|
+
if (binding.outputPath) {
|
|
1082
|
+
const existing = (_a = get(outputUi, binding.outputPath)) != null ? _a : {};
|
|
1083
|
+
set(outputUi, binding.outputPath, { ...existing, ...nodeUi });
|
|
1084
|
+
} else {
|
|
1085
|
+
Object.assign(outputUi, nodeUi);
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
const { references: outputReferences, resources: outputResources } = collectSchemaRefs(output, false);
|
|
1089
|
+
return {
|
|
1090
|
+
output,
|
|
1091
|
+
outputUi,
|
|
1092
|
+
outputReferences,
|
|
1093
|
+
outputResources
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
|
|
1097
|
+
// src/domain/contexts/utils.ts
|
|
1098
|
+
import {
|
|
1099
|
+
WorkflowExecutionTaskStatus,
|
|
1100
|
+
WorkflowTaskType as WorkflowTaskType3,
|
|
1101
|
+
WorkflowTriggerType as WorkflowTriggerType4
|
|
1102
|
+
} from "@livechat/developer-studio-api";
|
|
1103
|
+
var getTriggerContext = (workflowBundle, workflowFrames, specification) => {
|
|
1104
|
+
var _a, _b, _c;
|
|
1105
|
+
if (!((_a = workflowBundle.workflow.trigger) == null ? void 0 : _a.type)) {
|
|
1106
|
+
return;
|
|
1107
|
+
}
|
|
1108
|
+
const stored = workflowBundle.workflow;
|
|
1109
|
+
const triggerDefinition2 = workflowBundle.workflow.trigger.type === WorkflowTriggerType4.webhookManual ? {
|
|
1110
|
+
...workflowBundle.workflow.trigger,
|
|
1111
|
+
webhook_url: (_b = stored.webhook_url) != null ? _b : stored.id ? `${getWorkflowsEnv("textApiUrl")}/workflow_platform/webhooks/${stored.id}` : void 0
|
|
1112
|
+
} : workflowBundle.workflow.trigger;
|
|
1113
|
+
const config = getWorkflowElementConfig(
|
|
1114
|
+
triggerDefinition2,
|
|
1115
|
+
(_c = workflowBundle.introspection) != null ? _c : { tasks: {} },
|
|
1116
|
+
specification
|
|
1117
|
+
);
|
|
1118
|
+
const element = {
|
|
1119
|
+
definition: triggerDefinition2,
|
|
1120
|
+
execution: workflowBundle.execution ? {
|
|
1121
|
+
name: workflowBundle.workflow.trigger.name,
|
|
1122
|
+
type: workflowBundle.workflow.trigger.type,
|
|
1123
|
+
status: WorkflowExecutionTaskStatus.Completed,
|
|
1124
|
+
inputData: {},
|
|
1125
|
+
outputData: workflowBundle.execution.data.input
|
|
1126
|
+
} : void 0
|
|
1127
|
+
};
|
|
1128
|
+
const execution = workflowBundle.execution && element.execution ? {
|
|
1129
|
+
isSuccess: true,
|
|
1130
|
+
timestamp: workflowBundle.execution.started_at,
|
|
1131
|
+
data: element.execution,
|
|
1132
|
+
runtimeData: element.definition
|
|
1133
|
+
} : void 0;
|
|
1134
|
+
const frame = workflowFrames.input;
|
|
1135
|
+
const environment = {
|
|
1136
|
+
workflow: {}
|
|
1137
|
+
};
|
|
1138
|
+
return {
|
|
1139
|
+
index: 1,
|
|
1140
|
+
config,
|
|
1141
|
+
data: element.definition,
|
|
1142
|
+
execution,
|
|
1143
|
+
frame,
|
|
1144
|
+
environment
|
|
1145
|
+
};
|
|
1146
|
+
};
|
|
1147
|
+
var getWorkflowInputFrame = (workflowBundle, specification) => {
|
|
1148
|
+
var _a, _b, _c, _d, _e;
|
|
1149
|
+
if (!((_a = workflowBundle.workflow.trigger) == null ? void 0 : _a.type)) {
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
const config = getWorkflowElementConfig(
|
|
1153
|
+
workflowBundle.workflow.trigger,
|
|
1154
|
+
(_b = workflowBundle.introspection) != null ? _b : { tasks: {} },
|
|
1155
|
+
specification
|
|
1156
|
+
);
|
|
1157
|
+
const execution = (_c = workflowBundle.execution) == null ? void 0 : _c.data.input;
|
|
1158
|
+
const output = generateObjectFromSchema(
|
|
1159
|
+
(_d = config.specification.output) != null ? _d : {},
|
|
1160
|
+
execution
|
|
1161
|
+
);
|
|
1162
|
+
const frame = {
|
|
1163
|
+
...output,
|
|
1164
|
+
__meta: {
|
|
1165
|
+
index: 1,
|
|
1166
|
+
basePath: "workflow.input",
|
|
1167
|
+
credentialId: workflowBundle.workflow.trigger.type === WorkflowTriggerType4.webhook ? workflowBundle.workflow.trigger.webhook.credential_id : "text",
|
|
1168
|
+
contentBasePath: config.specification.metadata.outputBasePath,
|
|
1169
|
+
config: {
|
|
1170
|
+
stale: false,
|
|
1171
|
+
customization: config.customization,
|
|
1172
|
+
specification: config.specification
|
|
1173
|
+
},
|
|
1174
|
+
properties: (_e = output == null ? void 0 : output.__meta.properties) != null ? _e : {}
|
|
1175
|
+
}
|
|
1176
|
+
};
|
|
1177
|
+
return frame;
|
|
1178
|
+
};
|
|
1179
|
+
var getTaskContext = (taskData, workflowBundle, triggerContext, specification, carrier) => {
|
|
1180
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1181
|
+
const config = getWorkflowElementConfig(
|
|
1182
|
+
taskData,
|
|
1183
|
+
(_a = workflowBundle.introspection) != null ? _a : { tasks: {} },
|
|
1184
|
+
specification,
|
|
1185
|
+
carrier.environment
|
|
1186
|
+
);
|
|
1187
|
+
const element = {
|
|
1188
|
+
definition: taskData,
|
|
1189
|
+
execution: workflowBundle.execution ? workflowBundle.execution.data.tasks.find(
|
|
1190
|
+
(taskExecution) => taskExecution.referenceTaskName === taskData.taskReferenceName
|
|
1191
|
+
) : void 0
|
|
1192
|
+
};
|
|
1193
|
+
const introspection = (_b = workflowBundle.introspection) == null ? void 0 : _b.tasks[taskData.taskReferenceName];
|
|
1194
|
+
const execution = workflowBundle.execution ? element.execution ? {
|
|
1195
|
+
isSuccess: element.execution.status === WorkflowExecutionTaskStatus.Completed,
|
|
1196
|
+
timestamp: void 0,
|
|
1197
|
+
data: element.execution,
|
|
1198
|
+
runtimeData: {
|
|
1199
|
+
inputParameters: element.execution.inputData
|
|
1200
|
+
}
|
|
1201
|
+
} : {
|
|
1202
|
+
isSuccess: false,
|
|
1203
|
+
timestamp: void 0,
|
|
1204
|
+
data: {
|
|
1205
|
+
inputData: void 0,
|
|
1206
|
+
outputData: void 0,
|
|
1207
|
+
referenceTaskName: taskData.taskReferenceName,
|
|
1208
|
+
taskDefName: taskData.name,
|
|
1209
|
+
taskType: taskData.type,
|
|
1210
|
+
status: WorkflowExecutionTaskStatus.NotExecuted
|
|
1211
|
+
},
|
|
1212
|
+
runtimeData: void 0
|
|
1213
|
+
} : void 0;
|
|
1214
|
+
const outputSchema = ((_c = config.specification.output) == null ? void 0 : _c.type) === "object" ? config.specification.output : void 0;
|
|
1215
|
+
const output = outputSchema ? generateObjectFromSchema(outputSchema, {
|
|
1216
|
+
output: (_d = element.execution) == null ? void 0 : _d.outputData
|
|
1217
|
+
}) : void 0;
|
|
1218
|
+
const frame = {
|
|
1219
|
+
...output,
|
|
1220
|
+
__meta: {
|
|
1221
|
+
index: carrier.currentTaskGlobalIndex,
|
|
1222
|
+
credentialId: taskData.type === WorkflowTaskType3.http ? taskData.inputParameters.http_request.credentialId : void 0,
|
|
1223
|
+
basePath: taskData.taskReferenceName,
|
|
1224
|
+
contentBasePath: config.specification.metadata.outputBasePath,
|
|
1225
|
+
config: {
|
|
1226
|
+
stale: (_e = introspection == null ? void 0 : introspection.stale) != null ? _e : false,
|
|
1227
|
+
customization: config.customization,
|
|
1228
|
+
specification: config.specification
|
|
1229
|
+
},
|
|
1230
|
+
properties: (_f = output == null ? void 0 : output.__meta.properties) != null ? _f : {}
|
|
1231
|
+
}
|
|
1232
|
+
};
|
|
1233
|
+
const environment = carrier.environment;
|
|
1234
|
+
const assets = carrier.assets;
|
|
1235
|
+
const newAssets = getTaskAssets(
|
|
1236
|
+
taskData,
|
|
1237
|
+
config.specification,
|
|
1238
|
+
carrier.assets
|
|
1239
|
+
);
|
|
1240
|
+
const suggestions = Object.entries(
|
|
1241
|
+
(_g = config.specification.inputReferences) != null ? _g : {}
|
|
1242
|
+
).reduce((acc, [name, paths]) => {
|
|
1243
|
+
const assetResource = assets[name];
|
|
1244
|
+
if (!assetResource) {
|
|
1245
|
+
return acc;
|
|
1246
|
+
}
|
|
1247
|
+
return paths.reduce((innerAcc, ref) => {
|
|
1248
|
+
var _a2;
|
|
1249
|
+
const suggestions2 = assetResource.map((assetRef) => ({
|
|
1250
|
+
isNotConfirmed: assetRef.isNotConfirmed,
|
|
1251
|
+
value: `\${${assetRef.reference.taskName}.${assetRef.reference.ref.value}}`,
|
|
1252
|
+
contextMatch: !ref.subject || !assetRef.subject || ref.subject === assetRef.subject
|
|
1253
|
+
}));
|
|
1254
|
+
return {
|
|
1255
|
+
...innerAcc,
|
|
1256
|
+
[ref.value]: [...(_a2 = innerAcc[ref.value]) != null ? _a2 : [], ...suggestions2]
|
|
1257
|
+
};
|
|
1258
|
+
}, acc);
|
|
1259
|
+
}, {});
|
|
1260
|
+
const actions = getWorkflowTaskActions(config, suggestions, triggerContext);
|
|
1261
|
+
const context = {
|
|
1262
|
+
index: carrier.currentTaskGlobalIndex,
|
|
1263
|
+
config,
|
|
1264
|
+
data: element.definition,
|
|
1265
|
+
introspection,
|
|
1266
|
+
execution,
|
|
1267
|
+
frame,
|
|
1268
|
+
environment,
|
|
1269
|
+
assets,
|
|
1270
|
+
suggestions,
|
|
1271
|
+
actions: Object.keys(actions).length > 0 ? actions : void 0
|
|
1272
|
+
};
|
|
1273
|
+
return {
|
|
1274
|
+
context,
|
|
1275
|
+
newAssets
|
|
1276
|
+
};
|
|
1277
|
+
};
|
|
1278
|
+
var getTaskContexts = (workflowBundle, workflowFrames, triggerContext, specification) => {
|
|
1279
|
+
var _a;
|
|
1280
|
+
function taskReducer(tasks, initial) {
|
|
1281
|
+
return tasks.reduce((result, taskData) => {
|
|
1282
|
+
const { context: taskContext, newAssets } = getTaskContext(
|
|
1283
|
+
taskData,
|
|
1284
|
+
workflowBundle,
|
|
1285
|
+
triggerContext,
|
|
1286
|
+
specification,
|
|
1287
|
+
result.carrier
|
|
1288
|
+
);
|
|
1289
|
+
result.contexts = {
|
|
1290
|
+
...result.contexts,
|
|
1291
|
+
[taskData.taskReferenceName]: taskContext
|
|
1292
|
+
};
|
|
1293
|
+
result.carrier = {
|
|
1294
|
+
assets: newAssets,
|
|
1295
|
+
environment: {
|
|
1296
|
+
...result.carrier.environment,
|
|
1297
|
+
[taskData.taskReferenceName]: taskContext.frame
|
|
1298
|
+
},
|
|
1299
|
+
currentTaskGlobalIndex: result.carrier.currentTaskGlobalIndex + 1
|
|
1300
|
+
};
|
|
1301
|
+
if (taskData.type === WorkflowTaskType3.switch) {
|
|
1302
|
+
if (taskData.name === SYSTEM_TASK_NAMES.condition) {
|
|
1303
|
+
taskData.decisionCases = {
|
|
1304
|
+
TRUE: taskData.decisionCases.TRUE || [],
|
|
1305
|
+
FALSE: taskData.decisionCases.FALSE || []
|
|
1306
|
+
};
|
|
1307
|
+
}
|
|
1308
|
+
return Object.entries(taskData.decisionCases).reduce(
|
|
1309
|
+
(innerResult, [_decisionCase, innerTasks]) => {
|
|
1310
|
+
const decisionCaseResults = taskReducer(innerTasks, {
|
|
1311
|
+
contexts: innerResult.contexts,
|
|
1312
|
+
carrier: {
|
|
1313
|
+
assets: result.carrier.assets,
|
|
1314
|
+
environment: result.carrier.environment,
|
|
1315
|
+
currentTaskGlobalIndex: innerResult.carrier.currentTaskGlobalIndex
|
|
1316
|
+
}
|
|
1317
|
+
});
|
|
1318
|
+
return {
|
|
1319
|
+
...decisionCaseResults,
|
|
1320
|
+
carrier: {
|
|
1321
|
+
assets: innerResult.carrier.assets,
|
|
1322
|
+
environment: innerResult.carrier.environment,
|
|
1323
|
+
currentTaskGlobalIndex: decisionCaseResults.carrier.currentTaskGlobalIndex
|
|
1324
|
+
}
|
|
1325
|
+
};
|
|
1326
|
+
},
|
|
1327
|
+
result
|
|
1328
|
+
);
|
|
1329
|
+
}
|
|
1330
|
+
if (taskData.type === WorkflowTaskType3.forkJoin) {
|
|
1331
|
+
return taskData.forkTasks.reduce((innerResult, innerTasks) => {
|
|
1332
|
+
const forkTaskResults = taskReducer(innerTasks, {
|
|
1333
|
+
contexts: innerResult.contexts,
|
|
1334
|
+
carrier: {
|
|
1335
|
+
assets: result.carrier.assets,
|
|
1336
|
+
environment: result.carrier.environment,
|
|
1337
|
+
currentTaskGlobalIndex: innerResult.carrier.currentTaskGlobalIndex
|
|
1338
|
+
}
|
|
1339
|
+
});
|
|
1340
|
+
return {
|
|
1341
|
+
...forkTaskResults,
|
|
1342
|
+
carrier: {
|
|
1343
|
+
assets: mergeAssets(
|
|
1344
|
+
innerResult.carrier.assets,
|
|
1345
|
+
forkTaskResults.carrier.assets
|
|
1346
|
+
),
|
|
1347
|
+
environment: {
|
|
1348
|
+
...innerResult.carrier.environment,
|
|
1349
|
+
...forkTaskResults.carrier.environment
|
|
1350
|
+
},
|
|
1351
|
+
currentTaskGlobalIndex: forkTaskResults.carrier.currentTaskGlobalIndex
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
}, result);
|
|
1355
|
+
}
|
|
1356
|
+
if (taskData.type === WorkflowTaskType3.doWhile) {
|
|
1357
|
+
const loopTaskResults = taskReducer(taskData.loopOver, {
|
|
1358
|
+
contexts: result.contexts,
|
|
1359
|
+
carrier: {
|
|
1360
|
+
assets: result.carrier.assets,
|
|
1361
|
+
environment: result.carrier.environment,
|
|
1362
|
+
currentTaskGlobalIndex: result.carrier.currentTaskGlobalIndex
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1365
|
+
const { context: richDoWhileContext, newAssets: richDoWhileAssets } = getTaskContext(
|
|
1366
|
+
taskData,
|
|
1367
|
+
workflowBundle,
|
|
1368
|
+
triggerContext,
|
|
1369
|
+
specification,
|
|
1370
|
+
loopTaskResults.carrier
|
|
1371
|
+
);
|
|
1372
|
+
return {
|
|
1373
|
+
...result,
|
|
1374
|
+
contexts: {
|
|
1375
|
+
...loopTaskResults.contexts,
|
|
1376
|
+
[taskData.taskReferenceName]: {
|
|
1377
|
+
...taskContext,
|
|
1378
|
+
environment: richDoWhileContext.environment,
|
|
1379
|
+
assets: richDoWhileAssets
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
};
|
|
1383
|
+
}
|
|
1384
|
+
return result;
|
|
1385
|
+
}, initial);
|
|
1386
|
+
}
|
|
1387
|
+
const initialAssets = (triggerContext == null ? void 0 : triggerContext.config.specification) ? getTriggerAssets(triggerContext.data, triggerContext.config.specification) : void 0;
|
|
1388
|
+
const initialEnvironment = {
|
|
1389
|
+
workflow: workflowFrames
|
|
1390
|
+
};
|
|
1391
|
+
const {
|
|
1392
|
+
contexts,
|
|
1393
|
+
carrier: { environment, assets }
|
|
1394
|
+
} = taskReducer(workflowBundle.workflow.definition.tasks, {
|
|
1395
|
+
contexts: {},
|
|
1396
|
+
carrier: {
|
|
1397
|
+
assets: initialAssets != null ? initialAssets : {},
|
|
1398
|
+
environment: initialEnvironment,
|
|
1399
|
+
currentTaskGlobalIndex: ((_a = workflowBundle.workflow.trigger) == null ? void 0 : _a.type) ? 2 : 1
|
|
1400
|
+
}
|
|
1401
|
+
});
|
|
1402
|
+
return {
|
|
1403
|
+
tasks: contexts,
|
|
1404
|
+
global: {
|
|
1405
|
+
assets,
|
|
1406
|
+
environment
|
|
1407
|
+
}
|
|
1408
|
+
};
|
|
1409
|
+
};
|
|
1410
|
+
var getWorkflowContexts = (workflow, sources = {}, dependencies = {}) => {
|
|
1411
|
+
var _a;
|
|
1412
|
+
const specification = (_a = dependencies.specification) != null ? _a : getSpecification();
|
|
1413
|
+
const input = { workflow, ...sources };
|
|
1414
|
+
const workflowFrames = {
|
|
1415
|
+
input: getWorkflowInputFrame(input, specification)
|
|
1416
|
+
};
|
|
1417
|
+
const trigger = getTriggerContext(input, workflowFrames, specification);
|
|
1418
|
+
const { tasks, global } = getTaskContexts(
|
|
1419
|
+
input,
|
|
1420
|
+
workflowFrames,
|
|
1421
|
+
trigger,
|
|
1422
|
+
specification
|
|
1423
|
+
);
|
|
1424
|
+
return {
|
|
1425
|
+
trigger,
|
|
1426
|
+
tasks,
|
|
1427
|
+
global
|
|
1428
|
+
};
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
// src/domain/credentials/utils.ts
|
|
1432
|
+
import {
|
|
1433
|
+
CredentialType,
|
|
1434
|
+
IntegrationNames
|
|
1435
|
+
} from "@livechat/developer-studio-api";
|
|
1436
|
+
import { getIntegrationsEnv } from "@livechat/platform-integrations/config";
|
|
1437
|
+
var getInternalCredentials = () => /* @__PURE__ */ new Map([
|
|
1438
|
+
[IntegrationNames.Shopify, getIntegrationsEnv("shopifyClientId")],
|
|
1439
|
+
[IntegrationNames.BigCommerce, getIntegrationsEnv("bigcommerceClientId")],
|
|
1440
|
+
[IntegrationNames.HubSpot, getIntegrationsEnv("hubspotClientId")],
|
|
1441
|
+
[IntegrationNames.Slack, getIntegrationsEnv("slackClientId")],
|
|
1442
|
+
[IntegrationNames.Mailchimp, getIntegrationsEnv("mailchimpClientId")],
|
|
1443
|
+
[IntegrationNames.Salesforce, getIntegrationsEnv("salesforceClientId")],
|
|
1444
|
+
[IntegrationNames.Klaviyo, getIntegrationsEnv("klaviyoClientId")],
|
|
1445
|
+
["google", getIntegrationsEnv("googleClientId")]
|
|
1446
|
+
]);
|
|
1447
|
+
var getWorkflowCredentials = (credentials) => {
|
|
1448
|
+
const internalCredentials = getInternalCredentials();
|
|
1449
|
+
return credentials.map((credential) => {
|
|
1450
|
+
let isInternal = credential.type === CredentialType.TextAuth;
|
|
1451
|
+
if (!isInternal && credential.type === CredentialType.OAuth2) {
|
|
1452
|
+
isInternal = internalCredentials.get(credential.provider) === credential.data.client_id;
|
|
1453
|
+
}
|
|
1454
|
+
return { ...credential, isInternal };
|
|
1455
|
+
});
|
|
1456
|
+
};
|
|
1457
|
+
var getWorkflowElementDefaultCredentialId = (elementProvider, credentials) => {
|
|
1458
|
+
if (elementProvider === OTHER_TYPES.SYSTEM) {
|
|
1459
|
+
return;
|
|
1460
|
+
}
|
|
1461
|
+
const providerCredentials = credentials.filter(
|
|
1462
|
+
(credential) => credential.provider === elementProvider
|
|
1463
|
+
);
|
|
1464
|
+
if (providerCredentials.length === 1) {
|
|
1465
|
+
return providerCredentials[0].name;
|
|
1466
|
+
} else if (providerCredentials.length > 1) {
|
|
1467
|
+
const internalCredentials = providerCredentials.filter(
|
|
1468
|
+
(credential) => credential.isInternal
|
|
1469
|
+
);
|
|
1470
|
+
if (internalCredentials.length === 1) {
|
|
1471
|
+
return internalCredentials[0].name;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
};
|
|
1475
|
+
|
|
1476
|
+
// src/domain/common/tasks/reduce.ts
|
|
1477
|
+
import { WorkflowTaskType as WorkflowTaskType4 } from "@livechat/developer-studio-api";
|
|
1478
|
+
function recursiveTaskReducer(tasks, reducer, level = 0) {
|
|
1479
|
+
return tasks.reduce((result, task, taskIndex, allTasks) => {
|
|
1480
|
+
const reducerResult = reducer(result, task, taskIndex, allTasks, level);
|
|
1481
|
+
if (reducerResult) {
|
|
1482
|
+
return reducerResult;
|
|
1483
|
+
}
|
|
1484
|
+
if (task.type === WorkflowTaskType4.switch) {
|
|
1485
|
+
return [
|
|
1486
|
+
...result,
|
|
1487
|
+
{
|
|
1488
|
+
...task,
|
|
1489
|
+
decisionCases: Object.fromEntries(
|
|
1490
|
+
Object.entries(task.decisionCases).map(
|
|
1491
|
+
([decisionCase, innerTasks]) => [
|
|
1492
|
+
decisionCase,
|
|
1493
|
+
recursiveTaskReducer(innerTasks, reducer, level + 1)
|
|
1494
|
+
]
|
|
1495
|
+
)
|
|
1496
|
+
)
|
|
1497
|
+
}
|
|
1498
|
+
];
|
|
1499
|
+
} else if (task.type === WorkflowTaskType4.forkJoin) {
|
|
1500
|
+
return [
|
|
1501
|
+
...result,
|
|
1502
|
+
{
|
|
1503
|
+
...task,
|
|
1504
|
+
forkTasks: task.forkTasks.map(
|
|
1505
|
+
(innerTasks) => recursiveTaskReducer(innerTasks, reducer, level + 1)
|
|
1506
|
+
)
|
|
1507
|
+
}
|
|
1508
|
+
];
|
|
1509
|
+
} else if (task.type === WorkflowTaskType4.doWhile) {
|
|
1510
|
+
return [
|
|
1511
|
+
...result,
|
|
1512
|
+
{
|
|
1513
|
+
...task,
|
|
1514
|
+
loopOver: recursiveTaskReducer(task.loopOver, reducer, level + 1)
|
|
1515
|
+
}
|
|
1516
|
+
];
|
|
1517
|
+
}
|
|
1518
|
+
return [...result, task];
|
|
1519
|
+
}, []);
|
|
1520
|
+
}
|
|
1521
|
+
function reduceTasksRecursively(tasks, reducer, initialValue, level = 0) {
|
|
1522
|
+
return tasks.reduce((accumulator, task, taskIndex, allTasks) => {
|
|
1523
|
+
let next = reducer(accumulator, task, taskIndex, allTasks, level);
|
|
1524
|
+
if (task.type === WorkflowTaskType4.switch) {
|
|
1525
|
+
next = Object.values(task.decisionCases).reduce(
|
|
1526
|
+
(innerAccumulator, innerTasks) => reduceTasksRecursively(
|
|
1527
|
+
innerTasks,
|
|
1528
|
+
reducer,
|
|
1529
|
+
innerAccumulator,
|
|
1530
|
+
level + 1
|
|
1531
|
+
),
|
|
1532
|
+
next
|
|
1533
|
+
);
|
|
1534
|
+
} else if (task.type === WorkflowTaskType4.forkJoin) {
|
|
1535
|
+
next = task.forkTasks.reduce(
|
|
1536
|
+
(innerAccumulator, innerTasks) => reduceTasksRecursively(
|
|
1537
|
+
innerTasks,
|
|
1538
|
+
reducer,
|
|
1539
|
+
innerAccumulator,
|
|
1540
|
+
level + 1
|
|
1541
|
+
),
|
|
1542
|
+
next
|
|
1543
|
+
);
|
|
1544
|
+
} else if (task.type === WorkflowTaskType4.doWhile) {
|
|
1545
|
+
next = reduceTasksRecursively(task.loopOver, reducer, next, level + 1);
|
|
1546
|
+
}
|
|
1547
|
+
return next;
|
|
1548
|
+
}, initialValue);
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
// src/domain/common/prefill.tsx
|
|
1552
|
+
var CONTAINER_TASK_TYPES = [
|
|
1553
|
+
WorkflowTaskType5.switch,
|
|
1554
|
+
WorkflowTaskType5.forkJoin,
|
|
1555
|
+
WorkflowTaskType5.doWhile
|
|
1556
|
+
];
|
|
1557
|
+
function isContainerTask(task) {
|
|
1558
|
+
return CONTAINER_TASK_TYPES.includes(task.type);
|
|
1559
|
+
}
|
|
1560
|
+
function applyChange(workflow, change) {
|
|
1561
|
+
const changed = mergeDeep(workflow, change);
|
|
1562
|
+
changed.definition.tasks = recursiveTaskReducer(
|
|
1563
|
+
changed.definition.tasks,
|
|
1564
|
+
(result, task) => {
|
|
1565
|
+
if (task.type === WorkflowTaskType5.join) {
|
|
1566
|
+
const forkTask = result.at(-1);
|
|
1567
|
+
return [
|
|
1568
|
+
...result,
|
|
1569
|
+
{
|
|
1570
|
+
...task,
|
|
1571
|
+
joinOn: forkTask.forkTasks.map((tasks) => {
|
|
1572
|
+
var _a;
|
|
1573
|
+
return (_a = tasks.at(-1)) == null ? void 0 : _a.taskReferenceName;
|
|
1574
|
+
}).filter(notEmpty)
|
|
1575
|
+
}
|
|
1576
|
+
];
|
|
1577
|
+
}
|
|
1578
|
+
}
|
|
1579
|
+
);
|
|
1580
|
+
return changed;
|
|
1581
|
+
}
|
|
1582
|
+
function assignDefaultCredential(element, context) {
|
|
1583
|
+
const { specification, introspection, credentials } = context;
|
|
1584
|
+
const config = getWorkflowElementConfig(
|
|
1585
|
+
element,
|
|
1586
|
+
introspection,
|
|
1587
|
+
specification
|
|
1588
|
+
);
|
|
1589
|
+
const { isEditable } = config.customization.flags;
|
|
1590
|
+
const { credentialPath } = config.specification.metadata;
|
|
1591
|
+
if (!credentialPath || !isEditable) {
|
|
1592
|
+
return element;
|
|
1593
|
+
}
|
|
1594
|
+
if (get2(element, credentialPath)) {
|
|
1595
|
+
return element;
|
|
1596
|
+
}
|
|
1597
|
+
const credentialId = getWorkflowElementDefaultCredentialId(
|
|
1598
|
+
config.customization.provider,
|
|
1599
|
+
credentials
|
|
1600
|
+
);
|
|
1601
|
+
if (!credentialId) {
|
|
1602
|
+
return element;
|
|
1603
|
+
}
|
|
1604
|
+
set2(element, credentialPath, credentialId);
|
|
1605
|
+
return element;
|
|
1606
|
+
}
|
|
1607
|
+
function applyDefaultCredentials(workflow, context) {
|
|
1608
|
+
var _a;
|
|
1609
|
+
const trigger = ((_a = workflow.trigger) == null ? void 0 : _a.type) ? assignDefaultCredential(workflow.trigger, context) : workflow.trigger;
|
|
1610
|
+
const tasks = recursiveTaskReducer(
|
|
1611
|
+
workflow.definition.tasks,
|
|
1612
|
+
(result, task) => {
|
|
1613
|
+
if (isContainerTask(task)) {
|
|
1614
|
+
return void 0;
|
|
1615
|
+
}
|
|
1616
|
+
return [...result, assignDefaultCredential(task, context)];
|
|
1617
|
+
}
|
|
1618
|
+
);
|
|
1619
|
+
return {
|
|
1620
|
+
...workflow,
|
|
1621
|
+
trigger,
|
|
1622
|
+
definition: {
|
|
1623
|
+
...workflow.definition,
|
|
1624
|
+
tasks
|
|
1625
|
+
}
|
|
1626
|
+
};
|
|
1627
|
+
}
|
|
1628
|
+
function applyWorkflowAssetBindings(workflow, context, previousContexts) {
|
|
1629
|
+
var _a, _b;
|
|
1630
|
+
const { specification, introspection } = context;
|
|
1631
|
+
function taskUpdater(taskData, taskConfig, assets) {
|
|
1632
|
+
var _a2, _b2, _c, _d;
|
|
1633
|
+
const prevAssets = (_b2 = (_a2 = previousContexts.tasks[taskData.taskReferenceName]) == null ? void 0 : _a2.assets) != null ? _b2 : {};
|
|
1634
|
+
Object.entries((_d = (_c = taskConfig.specification) == null ? void 0 : _c.inputReferences) != null ? _d : {}).forEach(
|
|
1635
|
+
([key, inputResourcePaths]) => {
|
|
1636
|
+
inputResourcePaths.forEach((path) => {
|
|
1637
|
+
var _a3, _b3, _c2;
|
|
1638
|
+
const value = (_a3 = jsonUtils.extractByPath(path.value, taskData)) == null ? void 0 : _a3[0];
|
|
1639
|
+
const currentAsset = assets[key];
|
|
1640
|
+
const currentAssetConfig = workflowReferences[key];
|
|
1641
|
+
if (currentAssetConfig.kind !== "resource" /* Resource */) {
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
if (!value || typeof value !== "string") {
|
|
1645
|
+
if ((currentAsset == null ? void 0 : currentAsset.length) === 1) {
|
|
1646
|
+
set2(
|
|
1647
|
+
taskData,
|
|
1648
|
+
path.value,
|
|
1649
|
+
jsonUtils.wrapWithTag(
|
|
1650
|
+
`${currentAsset[0].reference.taskName}.${currentAsset[0].reference.ref.value}`
|
|
1651
|
+
)
|
|
1652
|
+
);
|
|
1653
|
+
}
|
|
1654
|
+
return;
|
|
1655
|
+
}
|
|
1656
|
+
if (!jsonUtils.containsTag(value)) {
|
|
1657
|
+
return;
|
|
1658
|
+
}
|
|
1659
|
+
if (!currentAsset) {
|
|
1660
|
+
set2(taskData, path.value, null);
|
|
1661
|
+
return;
|
|
1662
|
+
}
|
|
1663
|
+
const prev = (_b3 = prevAssets[key]) == null ? void 0 : _b3.find(
|
|
1664
|
+
(x) => value.includes(
|
|
1665
|
+
`\${${x.reference.taskName}.${x.reference.ref.value}}`
|
|
1666
|
+
)
|
|
1667
|
+
);
|
|
1668
|
+
const currentAssetResource = (_c2 = currentAsset.find(
|
|
1669
|
+
(a) => a.reference.ref.value === (prev == null ? void 0 : prev.reference.ref.value) && a.reference.taskName === prev.reference.taskName
|
|
1670
|
+
)) != null ? _c2 : currentAsset.length === 1 ? currentAsset[0] : void 0;
|
|
1671
|
+
if (!currentAssetResource) {
|
|
1672
|
+
set2(taskData, path.value, null);
|
|
1673
|
+
return;
|
|
1674
|
+
}
|
|
1675
|
+
set2(
|
|
1676
|
+
taskData,
|
|
1677
|
+
path.value,
|
|
1678
|
+
jsonUtils.wrapWithTag(
|
|
1679
|
+
`${currentAssetResource.reference.taskName}.${currentAssetResource.reference.ref.value}`
|
|
1680
|
+
)
|
|
1681
|
+
);
|
|
1682
|
+
});
|
|
1683
|
+
}
|
|
1684
|
+
);
|
|
1685
|
+
return taskData;
|
|
1686
|
+
}
|
|
1687
|
+
function taskReducer(tasks2, initial) {
|
|
1688
|
+
return tasks2.reduce((result, taskData) => {
|
|
1689
|
+
const taskConfig = getWorkflowElementConfig(
|
|
1690
|
+
taskData,
|
|
1691
|
+
introspection,
|
|
1692
|
+
specification
|
|
1693
|
+
);
|
|
1694
|
+
const updatedTaskData = taskUpdater(
|
|
1695
|
+
taskData,
|
|
1696
|
+
taskConfig,
|
|
1697
|
+
result.carrier.assets
|
|
1698
|
+
);
|
|
1699
|
+
const taskAssets = taskConfig.specification ? getTaskAssets(
|
|
1700
|
+
updatedTaskData,
|
|
1701
|
+
taskConfig.specification,
|
|
1702
|
+
result.carrier.assets
|
|
1703
|
+
) : {};
|
|
1704
|
+
result.carrier = {
|
|
1705
|
+
assets: taskAssets
|
|
1706
|
+
};
|
|
1707
|
+
if (updatedTaskData.type === WorkflowTaskType5.switch) {
|
|
1708
|
+
result.tasks = [
|
|
1709
|
+
...result.tasks,
|
|
1710
|
+
{
|
|
1711
|
+
...updatedTaskData,
|
|
1712
|
+
decisionCases: Object.fromEntries(
|
|
1713
|
+
Object.entries(updatedTaskData.decisionCases).map(
|
|
1714
|
+
([decisionCase, innerTasks]) => {
|
|
1715
|
+
const decisionCaseResults = taskReducer(innerTasks, {
|
|
1716
|
+
tasks: [],
|
|
1717
|
+
carrier: {
|
|
1718
|
+
assets: initial.carrier.assets
|
|
1719
|
+
}
|
|
1720
|
+
});
|
|
1721
|
+
return [decisionCase, decisionCaseResults.tasks];
|
|
1722
|
+
}
|
|
1723
|
+
)
|
|
1724
|
+
)
|
|
1725
|
+
}
|
|
1726
|
+
];
|
|
1727
|
+
} else if (updatedTaskData.type === WorkflowTaskType5.forkJoin) {
|
|
1728
|
+
result.tasks = [
|
|
1729
|
+
...result.tasks,
|
|
1730
|
+
{
|
|
1731
|
+
...updatedTaskData,
|
|
1732
|
+
forkTasks: updatedTaskData.forkTasks.map((innerTasks) => {
|
|
1733
|
+
const forkTaskResults = taskReducer(innerTasks, {
|
|
1734
|
+
tasks: [],
|
|
1735
|
+
carrier: {
|
|
1736
|
+
assets: initial.carrier.assets
|
|
1737
|
+
}
|
|
1738
|
+
});
|
|
1739
|
+
return forkTaskResults.tasks;
|
|
1740
|
+
})
|
|
1741
|
+
}
|
|
1742
|
+
];
|
|
1743
|
+
} else if (updatedTaskData.type === WorkflowTaskType5.doWhile) {
|
|
1744
|
+
const loopTaskResults = taskReducer(updatedTaskData.loopOver, {
|
|
1745
|
+
tasks: [],
|
|
1746
|
+
carrier: {
|
|
1747
|
+
assets: initial.carrier.assets
|
|
1748
|
+
}
|
|
1749
|
+
});
|
|
1750
|
+
result.tasks = [
|
|
1751
|
+
...result.tasks,
|
|
1752
|
+
{
|
|
1753
|
+
...updatedTaskData,
|
|
1754
|
+
loopOver: loopTaskResults.tasks
|
|
1755
|
+
}
|
|
1756
|
+
];
|
|
1757
|
+
} else {
|
|
1758
|
+
result.tasks = [...result.tasks, updatedTaskData];
|
|
1759
|
+
}
|
|
1760
|
+
return result;
|
|
1761
|
+
}, initial);
|
|
1762
|
+
}
|
|
1763
|
+
const triggerConfig = ((_a = workflow.trigger) == null ? void 0 : _a.type) ? getWorkflowElementConfig(workflow.trigger, introspection, specification) : void 0;
|
|
1764
|
+
const triggerAssets = ((_b = workflow.trigger) == null ? void 0 : _b.type) && (triggerConfig == null ? void 0 : triggerConfig.specification) ? getTriggerAssets(workflow.trigger, triggerConfig.specification) : {};
|
|
1765
|
+
const { tasks } = taskReducer(workflow.definition.tasks, {
|
|
1766
|
+
tasks: [],
|
|
1767
|
+
carrier: {
|
|
1768
|
+
assets: triggerAssets
|
|
1769
|
+
}
|
|
1770
|
+
});
|
|
1771
|
+
return {
|
|
1772
|
+
...workflow,
|
|
1773
|
+
definition: {
|
|
1774
|
+
...workflow.definition,
|
|
1775
|
+
tasks
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
}
|
|
1779
|
+
function prefillWorkflow(workflow, sources, dependencies) {
|
|
1780
|
+
var _a, _b;
|
|
1781
|
+
const specification = (_a = dependencies.specification) != null ? _a : getSpecification();
|
|
1782
|
+
const introspection = (_b = sources.introspection) != null ? _b : { tasks: {} };
|
|
1783
|
+
const normalized = applyChange(
|
|
1784
|
+
cloneDeep2(workflow),
|
|
1785
|
+
{}
|
|
1786
|
+
);
|
|
1787
|
+
const withCredentials = applyDefaultCredentials(normalized, {
|
|
1788
|
+
...dependencies,
|
|
1789
|
+
specification,
|
|
1790
|
+
introspection
|
|
1791
|
+
});
|
|
1792
|
+
const previousContexts = getWorkflowContexts(
|
|
1793
|
+
withCredentials,
|
|
1794
|
+
{ introspection },
|
|
1795
|
+
{ specification }
|
|
1796
|
+
);
|
|
1797
|
+
return applyWorkflowAssetBindings(
|
|
1798
|
+
withCredentials,
|
|
1799
|
+
{ specification, introspection },
|
|
1800
|
+
previousContexts
|
|
1801
|
+
);
|
|
1802
|
+
}
|
|
1803
|
+
|
|
1804
|
+
// src/utils/schemaValidation.ts
|
|
1805
|
+
import Ajv from "ajv";
|
|
1806
|
+
import AjvWithErrors from "ajv-errors";
|
|
1807
|
+
import addFormats from "ajv-formats";
|
|
1808
|
+
import AjvWithKeywords from "ajv-keywords";
|
|
1809
|
+
function collectAllErrors(schemaNode) {
|
|
1810
|
+
let errors = [];
|
|
1811
|
+
if (Array.isArray(schemaNode.__errorsExtended)) {
|
|
1812
|
+
errors = errors.concat(schemaNode.__errorsExtended);
|
|
1813
|
+
}
|
|
1814
|
+
for (const key in schemaNode) {
|
|
1815
|
+
const node = schemaNode[key];
|
|
1816
|
+
if (!key.startsWith("__") && typeof node === "object") {
|
|
1817
|
+
errors = errors.concat(collectAllErrors(node));
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
return errors;
|
|
1821
|
+
}
|
|
1822
|
+
var buildErrorSchema = (validationErrors, data) => {
|
|
1823
|
+
const adjustedErrors = validationErrors.map((rawError) => {
|
|
1824
|
+
var _a;
|
|
1825
|
+
let error = rawError;
|
|
1826
|
+
let overrideMessage = true;
|
|
1827
|
+
if (error.keyword === "errorMessage") {
|
|
1828
|
+
const customError = error;
|
|
1829
|
+
const innerError = customError.params.errors[0];
|
|
1830
|
+
if (innerError) {
|
|
1831
|
+
error = {
|
|
1832
|
+
...error,
|
|
1833
|
+
keyword: innerError.keyword,
|
|
1834
|
+
params: innerError.params,
|
|
1835
|
+
schemaPath: innerError.schemaPath
|
|
1836
|
+
};
|
|
1837
|
+
overrideMessage = false;
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
if ("missingProperty" in error.params) {
|
|
1841
|
+
if (error.params.missingProperty) {
|
|
1842
|
+
error.instancePath = `${error.instancePath}/${error.params.missingProperty}`;
|
|
1843
|
+
error.keyword = "requiredProperty";
|
|
1844
|
+
if (error.params.missingProperty === "credentialId") {
|
|
1845
|
+
error.keyword = "connection";
|
|
1846
|
+
}
|
|
1847
|
+
if (overrideMessage) {
|
|
1848
|
+
error.message = "property is required";
|
|
1849
|
+
}
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
if (overrideMessage) {
|
|
1853
|
+
switch (error.keyword) {
|
|
1854
|
+
case "type": {
|
|
1855
|
+
const instanceJsonPath = error.instancePath.slice(1);
|
|
1856
|
+
const value = instanceJsonPath ? (_a = jsonUtils.extractByPath(
|
|
1857
|
+
instanceJsonPath.replaceAll("/", "."),
|
|
1858
|
+
data
|
|
1859
|
+
)) == null ? void 0 : _a[0] : void 0;
|
|
1860
|
+
if (value === null) {
|
|
1861
|
+
error.message = "This field cannot be empty";
|
|
1862
|
+
} else {
|
|
1863
|
+
error.message = "Invalid value type";
|
|
1864
|
+
}
|
|
1865
|
+
break;
|
|
1866
|
+
}
|
|
1867
|
+
case "required":
|
|
1868
|
+
error.message = `Field '${error.params.missingProperty}' is required`;
|
|
1869
|
+
break;
|
|
1870
|
+
case "requiredProperty":
|
|
1871
|
+
error.message = "This field cannot be empty";
|
|
1872
|
+
break;
|
|
1873
|
+
case "minLength":
|
|
1874
|
+
error.message = `Must have more than ${error.params.limit} characters`;
|
|
1875
|
+
break;
|
|
1876
|
+
case "const":
|
|
1877
|
+
error.message = "Must be one of enumeration";
|
|
1878
|
+
break;
|
|
1879
|
+
default:
|
|
1880
|
+
break;
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
return error;
|
|
1884
|
+
}).map((error) => {
|
|
1885
|
+
var _a;
|
|
1886
|
+
const instanceJsonPath = error.instancePath.slice(1);
|
|
1887
|
+
const value = instanceJsonPath ? (_a = jsonUtils.extractByPath(
|
|
1888
|
+
instanceJsonPath.replaceAll("/", "."),
|
|
1889
|
+
data
|
|
1890
|
+
)) == null ? void 0 : _a[0] : void 0;
|
|
1891
|
+
if (typeof value === "string" && ["format", "pattern", "const", "enum", "oneOf"].includes(error.keyword)) {
|
|
1892
|
+
if (error.keyword === "format" && error.params.format === "json") {
|
|
1893
|
+
return error;
|
|
1894
|
+
}
|
|
1895
|
+
if (jsonUtils.containsTag(value)) {
|
|
1896
|
+
return;
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
return error;
|
|
1900
|
+
}).filter(notEmpty);
|
|
1901
|
+
const errors = {};
|
|
1902
|
+
function addToErrorSchema(current, path, item) {
|
|
1903
|
+
var _a;
|
|
1904
|
+
const [head, ...tail] = path;
|
|
1905
|
+
if (!head) {
|
|
1906
|
+
return false;
|
|
1907
|
+
}
|
|
1908
|
+
if (tail.length === 0) {
|
|
1909
|
+
if (!current[head]) {
|
|
1910
|
+
current[head] = {};
|
|
1911
|
+
}
|
|
1912
|
+
const fieldErrors = current[head];
|
|
1913
|
+
if (item.message && item.message !== 'must match "then" schema' && item.message !== 'must match "else" schema') {
|
|
1914
|
+
if (!fieldErrors.__errors) {
|
|
1915
|
+
fieldErrors.__errors = [];
|
|
1916
|
+
}
|
|
1917
|
+
if (!fieldErrors.__errorsExtended) {
|
|
1918
|
+
fieldErrors.__errorsExtended = [];
|
|
1919
|
+
}
|
|
1920
|
+
fieldErrors.__errors.push(item.message);
|
|
1921
|
+
fieldErrors.__errorsExtended.push(item);
|
|
1922
|
+
if (item.keyword) {
|
|
1923
|
+
(_a = fieldErrors.__errorsByKeyword) != null ? _a : fieldErrors.__errorsByKeyword = {};
|
|
1924
|
+
fieldErrors.__errorsByKeyword[item.keyword] = item;
|
|
1925
|
+
}
|
|
1926
|
+
return true;
|
|
1927
|
+
}
|
|
1928
|
+
return Object.keys(fieldErrors).length > 0;
|
|
1929
|
+
}
|
|
1930
|
+
if (!current[head]) {
|
|
1931
|
+
current[head] = {};
|
|
1932
|
+
}
|
|
1933
|
+
const hasError = addToErrorSchema(
|
|
1934
|
+
current[head],
|
|
1935
|
+
tail,
|
|
1936
|
+
item
|
|
1937
|
+
);
|
|
1938
|
+
if (!hasError) {
|
|
1939
|
+
delete current[head];
|
|
1940
|
+
return Object.keys(current).length > 0;
|
|
1941
|
+
}
|
|
1942
|
+
return true;
|
|
1943
|
+
}
|
|
1944
|
+
if (adjustedErrors.length > 0) {
|
|
1945
|
+
adjustedErrors.forEach((item) => {
|
|
1946
|
+
const path = item.instancePath.split("/").filter(Boolean);
|
|
1947
|
+
addToErrorSchema(errors, path, item);
|
|
1948
|
+
});
|
|
1949
|
+
}
|
|
1950
|
+
return errors;
|
|
1951
|
+
};
|
|
1952
|
+
var getValidator = (schema) => {
|
|
1953
|
+
const ajv = new Ajv({
|
|
1954
|
+
strict: false,
|
|
1955
|
+
allErrors: true,
|
|
1956
|
+
inlineRefs: false
|
|
1957
|
+
});
|
|
1958
|
+
addFormats(ajv);
|
|
1959
|
+
ajv.addFormat("json", {
|
|
1960
|
+
type: "string",
|
|
1961
|
+
validate: (data) => {
|
|
1962
|
+
try {
|
|
1963
|
+
JSON.parse(data);
|
|
1964
|
+
return true;
|
|
1965
|
+
} catch (e) {
|
|
1966
|
+
return false;
|
|
1967
|
+
}
|
|
1968
|
+
}
|
|
1969
|
+
});
|
|
1970
|
+
return AjvWithKeywords(AjvWithErrors(ajv)).compile(schema);
|
|
1971
|
+
};
|
|
1972
|
+
|
|
1973
|
+
// src/domain/validation/schema/full.ts
|
|
1974
|
+
import {
|
|
1975
|
+
WorkflowItemKind as WorkflowItemKind2,
|
|
1976
|
+
WorkflowTriggerType as WorkflowTriggerType5
|
|
1977
|
+
} from "@livechat/developer-studio-api";
|
|
1978
|
+
|
|
1979
|
+
// src/domain/validation/schema/defs.ts
|
|
1980
|
+
var jsonSchemaBaseOptions = [
|
|
1981
|
+
{
|
|
1982
|
+
const: "string",
|
|
1983
|
+
title: "String",
|
|
1984
|
+
"x-group": "Simple Types"
|
|
1985
|
+
},
|
|
1986
|
+
{
|
|
1987
|
+
const: "number",
|
|
1988
|
+
title: "Number",
|
|
1989
|
+
"x-group": "Simple Types"
|
|
1990
|
+
},
|
|
1991
|
+
{
|
|
1992
|
+
const: "boolean",
|
|
1993
|
+
title: "Boolean",
|
|
1994
|
+
"x-group": "Simple Types"
|
|
1995
|
+
},
|
|
1996
|
+
{
|
|
1997
|
+
const: `references/${LIVECHAT_REFERENCE_NAMES.Chat}`,
|
|
1998
|
+
title: "Chat",
|
|
1999
|
+
"x-group": "References"
|
|
2000
|
+
},
|
|
2001
|
+
{
|
|
2002
|
+
const: `references/${LIVECHAT_REFERENCE_NAMES.Thread}`,
|
|
2003
|
+
title: "Thread",
|
|
2004
|
+
"x-group": "References"
|
|
2005
|
+
},
|
|
2006
|
+
{
|
|
2007
|
+
const: `references/${HELPDESK_REFERENCE_NAMES.Ticket}`,
|
|
2008
|
+
title: "Ticket",
|
|
2009
|
+
"x-group": "References"
|
|
2010
|
+
}
|
|
2011
|
+
];
|
|
2012
|
+
var jsonSchema = {
|
|
2013
|
+
type: "object",
|
|
2014
|
+
default: {
|
|
2015
|
+
title: "",
|
|
2016
|
+
description: "",
|
|
2017
|
+
type: "string"
|
|
2018
|
+
},
|
|
2019
|
+
required: ["title", "description", "type"],
|
|
2020
|
+
properties: {
|
|
2021
|
+
title: {
|
|
2022
|
+
type: "string",
|
|
2023
|
+
title: "Title"
|
|
2024
|
+
},
|
|
2025
|
+
description: {
|
|
2026
|
+
type: "string",
|
|
2027
|
+
title: "Description"
|
|
2028
|
+
},
|
|
2029
|
+
type: {
|
|
2030
|
+
type: "string",
|
|
2031
|
+
title: "Type",
|
|
2032
|
+
default: "string",
|
|
2033
|
+
oneOf: [
|
|
2034
|
+
...jsonSchemaBaseOptions,
|
|
2035
|
+
{
|
|
2036
|
+
const: "object",
|
|
2037
|
+
title: "Object",
|
|
2038
|
+
"x-group": "Simple Types"
|
|
2039
|
+
},
|
|
2040
|
+
{
|
|
2041
|
+
const: "array",
|
|
2042
|
+
title: "Array",
|
|
2043
|
+
"x-group": "Simple Types"
|
|
2044
|
+
}
|
|
2045
|
+
]
|
|
2046
|
+
}
|
|
2047
|
+
},
|
|
2048
|
+
allOf: [
|
|
2049
|
+
{
|
|
2050
|
+
if: {
|
|
2051
|
+
properties: { type: { const: "object" } },
|
|
2052
|
+
required: ["type"]
|
|
2053
|
+
},
|
|
2054
|
+
then: {
|
|
2055
|
+
properties: {
|
|
2056
|
+
properties: {
|
|
2057
|
+
type: "object",
|
|
2058
|
+
title: "Properties",
|
|
2059
|
+
visible: true,
|
|
2060
|
+
patternProperties: {
|
|
2061
|
+
".*": {
|
|
2062
|
+
$ref: "#/$defs/jsonSchema"
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
},
|
|
2069
|
+
{
|
|
2070
|
+
if: {
|
|
2071
|
+
properties: { type: { const: "array" } },
|
|
2072
|
+
required: ["type"]
|
|
2073
|
+
},
|
|
2074
|
+
then: {
|
|
2075
|
+
required: ["title", "description", "type", "items"],
|
|
2076
|
+
properties: {
|
|
2077
|
+
items: {
|
|
2078
|
+
title: "Items",
|
|
2079
|
+
$ref: "#/$defs/jsonSchema"
|
|
2080
|
+
}
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
},
|
|
2084
|
+
{
|
|
2085
|
+
if: {
|
|
2086
|
+
properties: { type: { const: "string" } },
|
|
2087
|
+
required: ["type"]
|
|
2088
|
+
},
|
|
2089
|
+
then: {
|
|
2090
|
+
properties: {}
|
|
2091
|
+
}
|
|
2092
|
+
},
|
|
2093
|
+
{
|
|
2094
|
+
if: {
|
|
2095
|
+
properties: { type: { const: "number" } },
|
|
2096
|
+
required: ["type"]
|
|
2097
|
+
},
|
|
2098
|
+
then: {
|
|
2099
|
+
properties: {}
|
|
2100
|
+
}
|
|
2101
|
+
}
|
|
2102
|
+
]
|
|
2103
|
+
};
|
|
2104
|
+
var jsonSchemaSimplified = {
|
|
2105
|
+
type: "object",
|
|
2106
|
+
default: {
|
|
2107
|
+
type: "string"
|
|
2108
|
+
},
|
|
2109
|
+
required: ["type"],
|
|
2110
|
+
properties: {
|
|
2111
|
+
type: {
|
|
2112
|
+
type: "string",
|
|
2113
|
+
title: "Type",
|
|
2114
|
+
default: "string",
|
|
2115
|
+
oneOf: jsonSchemaBaseOptions
|
|
2116
|
+
}
|
|
2117
|
+
}
|
|
2118
|
+
};
|
|
2119
|
+
|
|
2120
|
+
// src/domain/validation/schema/full.ts
|
|
2121
|
+
var itemVersionCondition = (type, name, version) => {
|
|
2122
|
+
const base = {
|
|
2123
|
+
required: ["type", "name"],
|
|
2124
|
+
properties: {
|
|
2125
|
+
type: { const: type },
|
|
2126
|
+
name: { const: name }
|
|
2127
|
+
}
|
|
2128
|
+
};
|
|
2129
|
+
const isWebhookTrigger = type === WorkflowTriggerType5.webhook;
|
|
2130
|
+
const versionMissing = isWebhookTrigger ? {
|
|
2131
|
+
properties: {
|
|
2132
|
+
webhook: {
|
|
2133
|
+
properties: {
|
|
2134
|
+
event: { not: { required: ["version"] } }
|
|
2135
|
+
}
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
} : { not: { required: ["version"] } };
|
|
2139
|
+
const versionMatches = (versionSchema) => isWebhookTrigger ? {
|
|
2140
|
+
required: ["webhook"],
|
|
2141
|
+
properties: {
|
|
2142
|
+
webhook: {
|
|
2143
|
+
required: ["event"],
|
|
2144
|
+
properties: {
|
|
2145
|
+
event: {
|
|
2146
|
+
required: ["version"],
|
|
2147
|
+
properties: { version: versionSchema }
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
}
|
|
2152
|
+
} : {
|
|
2153
|
+
required: ["version"],
|
|
2154
|
+
properties: { version: versionSchema }
|
|
2155
|
+
};
|
|
2156
|
+
if (version === "v0") {
|
|
2157
|
+
return {
|
|
2158
|
+
allOf: [
|
|
2159
|
+
base,
|
|
2160
|
+
{
|
|
2161
|
+
anyOf: [versionMissing, versionMatches({ enum: ["v0", null] })]
|
|
2162
|
+
}
|
|
2163
|
+
]
|
|
2164
|
+
};
|
|
2165
|
+
}
|
|
2166
|
+
return {
|
|
2167
|
+
allOf: [base, versionMatches({ const: version })]
|
|
2168
|
+
};
|
|
2169
|
+
};
|
|
2170
|
+
var collectSpecEntries = (kind) => Object.values(rawItemConfigs).filter((item) => item.kind === kind).flatMap(
|
|
2171
|
+
(config) => Object.entries(config.specifications.versions).map((version) => ({
|
|
2172
|
+
config,
|
|
2173
|
+
version
|
|
2174
|
+
}))
|
|
2175
|
+
);
|
|
2176
|
+
var taskSpecEntries = collectSpecEntries(WorkflowItemKind2.Task);
|
|
2177
|
+
var triggerSpecEntries = collectSpecEntries(WorkflowItemKind2.Trigger);
|
|
2178
|
+
var taskSchemas = Object.fromEntries(
|
|
2179
|
+
taskSpecEntries.map(({ config, version: [version, specification] }) => [
|
|
2180
|
+
`${config.key}_${version}`,
|
|
2181
|
+
specification.input
|
|
2182
|
+
])
|
|
2183
|
+
);
|
|
2184
|
+
var tasksDefinition = {
|
|
2185
|
+
type: "array",
|
|
2186
|
+
default: [],
|
|
2187
|
+
items: {
|
|
2188
|
+
allOf: taskSpecEntries.map(
|
|
2189
|
+
({ config, version: [version, specification] }) => ({
|
|
2190
|
+
if: itemVersionCondition(
|
|
2191
|
+
specification.template.type,
|
|
2192
|
+
config.key,
|
|
2193
|
+
version
|
|
2194
|
+
),
|
|
2195
|
+
then: {
|
|
2196
|
+
$ref: `#/$defs/taskSchemas/${config.key}_${version}`
|
|
2197
|
+
}
|
|
2198
|
+
})
|
|
2199
|
+
)
|
|
2200
|
+
}
|
|
2201
|
+
};
|
|
2202
|
+
var triggerDefinition = [
|
|
2203
|
+
{
|
|
2204
|
+
if: {
|
|
2205
|
+
properties: { type: { const: void 0 } }
|
|
2206
|
+
},
|
|
2207
|
+
then: {
|
|
2208
|
+
required: ["type"],
|
|
2209
|
+
properties: { type: { type: "string" } },
|
|
2210
|
+
errorMessage: { required: "Add a trigger to start your workflow" }
|
|
2211
|
+
}
|
|
2212
|
+
},
|
|
2213
|
+
...triggerSpecEntries.map(
|
|
2214
|
+
({ config, version: [version, specification] }) => ({
|
|
2215
|
+
if: itemVersionCondition(
|
|
2216
|
+
specification.template.type,
|
|
2217
|
+
config.key,
|
|
2218
|
+
version
|
|
2219
|
+
),
|
|
2220
|
+
then: specification.input
|
|
2221
|
+
})
|
|
2222
|
+
)
|
|
2223
|
+
];
|
|
2224
|
+
var WORKFLOW_SCHEMA_DEFS = {
|
|
2225
|
+
$defs: {
|
|
2226
|
+
tasks: tasksDefinition,
|
|
2227
|
+
references: workflowReferences,
|
|
2228
|
+
resources: workflowResources,
|
|
2229
|
+
jsonSchema,
|
|
2230
|
+
taskSchemas,
|
|
2231
|
+
jsonSchemaSimplified
|
|
2232
|
+
}
|
|
2233
|
+
};
|
|
2234
|
+
var workflowSchema = {
|
|
2235
|
+
$schema: "http://json-schema.org/draft-07/schema",
|
|
2236
|
+
type: "object",
|
|
2237
|
+
title: "The root schema",
|
|
2238
|
+
description: "The root schema comprises the entire JSON document.",
|
|
2239
|
+
default: {},
|
|
2240
|
+
examples: [
|
|
2241
|
+
{
|
|
2242
|
+
name: "first_sample_workflow",
|
|
2243
|
+
description: "First Sample Workflow",
|
|
2244
|
+
version: 1,
|
|
2245
|
+
definition: {
|
|
2246
|
+
tasks: [
|
|
2247
|
+
{
|
|
2248
|
+
name: "get_population_data",
|
|
2249
|
+
taskReferenceName: "get_population_data",
|
|
2250
|
+
inputParameters: {
|
|
2251
|
+
http_request: {
|
|
2252
|
+
uri: "https://datausa.io/api/data?drilldowns=Nation&measures=Population",
|
|
2253
|
+
method: "GET"
|
|
2254
|
+
}
|
|
2255
|
+
},
|
|
2256
|
+
type: "HTTP"
|
|
2257
|
+
}
|
|
2258
|
+
],
|
|
2259
|
+
inputParameters: null,
|
|
2260
|
+
outputParameters: {
|
|
2261
|
+
data: "${get_population_data.output.response.body.data}",
|
|
2262
|
+
source: "${get_population_data.output.response.body.source}"
|
|
2263
|
+
},
|
|
2264
|
+
schemaVersion: 2,
|
|
2265
|
+
restartable: true,
|
|
2266
|
+
workflowStatusListenerEnabled: false,
|
|
2267
|
+
timeoutPolicy: "ALERT_ONLY",
|
|
2268
|
+
timeoutSeconds: 0
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
],
|
|
2272
|
+
properties: {
|
|
2273
|
+
name: {
|
|
2274
|
+
$id: "#/properties/name",
|
|
2275
|
+
default: "",
|
|
2276
|
+
description: "Workflow Name - should be without spaces or special characters. Underscores and periods are allowed.",
|
|
2277
|
+
maxLength: 100,
|
|
2278
|
+
minLength: 1,
|
|
2279
|
+
title: "Workflow Name",
|
|
2280
|
+
type: "string"
|
|
2281
|
+
},
|
|
2282
|
+
description: {
|
|
2283
|
+
$id: "#/properties/description",
|
|
2284
|
+
type: "string",
|
|
2285
|
+
title: "Workflow Description",
|
|
2286
|
+
description: "An brief description of your workflow for reference.",
|
|
2287
|
+
default: "",
|
|
2288
|
+
examples: ["First Sample Workflow"]
|
|
2289
|
+
},
|
|
2290
|
+
version: {
|
|
2291
|
+
$id: "#/properties/version",
|
|
2292
|
+
default: 0,
|
|
2293
|
+
description: "An explanation about the purpose of this instance.",
|
|
2294
|
+
examples: [1],
|
|
2295
|
+
title: "The version schema",
|
|
2296
|
+
minimum: 0,
|
|
2297
|
+
type: "integer"
|
|
2298
|
+
},
|
|
2299
|
+
definition: {
|
|
2300
|
+
$id: "#/properties/definition",
|
|
2301
|
+
type: "object",
|
|
2302
|
+
title: "Workflow Definition",
|
|
2303
|
+
description: "This object holds the definition of your workflow.",
|
|
2304
|
+
default: {},
|
|
2305
|
+
properties: {
|
|
2306
|
+
tasks: {
|
|
2307
|
+
$id: "#/properties/definition/tasks",
|
|
2308
|
+
$ref: "#/$defs/tasks",
|
|
2309
|
+
minItems: 1,
|
|
2310
|
+
title: "Workflow Tasks",
|
|
2311
|
+
description: "This list holds the tasks for your workflow.",
|
|
2312
|
+
errorMessage: {
|
|
2313
|
+
minItems: "Add an action to complete your workflow."
|
|
2314
|
+
}
|
|
2315
|
+
},
|
|
2316
|
+
inputParameters: {
|
|
2317
|
+
$id: "#/properties/definition/inputParameters",
|
|
2318
|
+
type: ["array", "null"],
|
|
2319
|
+
title: "Workflow Input Parameters",
|
|
2320
|
+
description: "An explanation about the purpose of this instance.",
|
|
2321
|
+
default: [],
|
|
2322
|
+
examples: [[]],
|
|
2323
|
+
items: {
|
|
2324
|
+
$id: "#/properties/inputParameters/items"
|
|
2325
|
+
}
|
|
2326
|
+
},
|
|
2327
|
+
outputParameters: {
|
|
2328
|
+
$id: "#/properties/definition/outputParameters",
|
|
2329
|
+
type: "object",
|
|
2330
|
+
title: "The outputParameters schema",
|
|
2331
|
+
description: "An explanation about the purpose of this instance.",
|
|
2332
|
+
default: {},
|
|
2333
|
+
examples: [
|
|
2334
|
+
{
|
|
2335
|
+
data: "${get_population_data.output.response.body.data}",
|
|
2336
|
+
source: "${get_population_data.output.response.body.source}"
|
|
2337
|
+
}
|
|
2338
|
+
],
|
|
2339
|
+
required: [],
|
|
2340
|
+
properties: {},
|
|
2341
|
+
additionalProperties: true
|
|
2342
|
+
},
|
|
2343
|
+
schemaVersion: {
|
|
2344
|
+
$id: "#/properties/definition/schemaVersion",
|
|
2345
|
+
type: "integer",
|
|
2346
|
+
title: "Schema Version",
|
|
2347
|
+
description: "Fixed schema version",
|
|
2348
|
+
default: 2,
|
|
2349
|
+
examples: [2]
|
|
2350
|
+
},
|
|
2351
|
+
restartable: {
|
|
2352
|
+
$id: "#/properties/definition/restartable",
|
|
2353
|
+
type: "boolean",
|
|
2354
|
+
title: "Workflow restartable",
|
|
2355
|
+
description: "Specify if the workflow is restartable.",
|
|
2356
|
+
default: true,
|
|
2357
|
+
examples: [true, false]
|
|
2358
|
+
},
|
|
2359
|
+
workflowStatusListenerEnabled: {
|
|
2360
|
+
$id: "#/properties/definition/workflowStatusListenerEnabled",
|
|
2361
|
+
type: "boolean",
|
|
2362
|
+
title: "The workflowStatusListenerEnabled schema",
|
|
2363
|
+
description: "An explanation about the purpose of this instance.",
|
|
2364
|
+
default: false,
|
|
2365
|
+
examples: [true, false]
|
|
2366
|
+
},
|
|
2367
|
+
timeoutPolicy: {
|
|
2368
|
+
$id: "#/properties/definition/timeoutPolicy",
|
|
2369
|
+
type: "string",
|
|
2370
|
+
title: "The timeoutPolicy schema",
|
|
2371
|
+
description: "An explanation about the purpose of this instance.",
|
|
2372
|
+
default: "",
|
|
2373
|
+
examples: ["ALERT_ONLY", "TIME_OUT_WF"]
|
|
2374
|
+
},
|
|
2375
|
+
timeoutSeconds: {
|
|
2376
|
+
$id: "#/properties/definition/timeoutSeconds",
|
|
2377
|
+
type: "integer",
|
|
2378
|
+
title: "The timeoutSeconds schema",
|
|
2379
|
+
description: "An explanation about the purpose of this instance.",
|
|
2380
|
+
default: 0,
|
|
2381
|
+
examples: [0]
|
|
2382
|
+
}
|
|
2383
|
+
}
|
|
2384
|
+
},
|
|
2385
|
+
trigger: {
|
|
2386
|
+
$id: "#/properties/trigger",
|
|
2387
|
+
type: "object",
|
|
2388
|
+
title: "Workflow Trigger",
|
|
2389
|
+
description: "This object holds the declaration of your workflow trigger.",
|
|
2390
|
+
default: {},
|
|
2391
|
+
allOf: triggerDefinition
|
|
2392
|
+
}
|
|
2393
|
+
},
|
|
2394
|
+
required: ["definition", "trigger"],
|
|
2395
|
+
$defs: WORKFLOW_SCHEMA_DEFS.$defs
|
|
2396
|
+
};
|
|
2397
|
+
|
|
2398
|
+
// src/domain/validation/utils.ts
|
|
2399
|
+
import {
|
|
2400
|
+
CredentialType as CredentialType2,
|
|
2401
|
+
IntegrationNames as IntegrationNames2,
|
|
2402
|
+
WorkflowExecutionTaskStatus as WorkflowExecutionTaskStatus2,
|
|
2403
|
+
WorkflowTaskType as WorkflowTaskType6,
|
|
2404
|
+
WorkflowTriggerType as WorkflowTriggerType6
|
|
2405
|
+
} from "@livechat/developer-studio-api";
|
|
2406
|
+
|
|
2407
|
+
// src/domain/validation/types.ts
|
|
2408
|
+
var WorkflowValidationErrorType = /* @__PURE__ */ ((WorkflowValidationErrorType2) => {
|
|
2409
|
+
WorkflowValidationErrorType2["Schema"] = "schema";
|
|
2410
|
+
WorkflowValidationErrorType2["Resolver"] = "resolver";
|
|
2411
|
+
WorkflowValidationErrorType2["Connection"] = "connection";
|
|
2412
|
+
WorkflowValidationErrorType2["Activation"] = "activation";
|
|
2413
|
+
WorkflowValidationErrorType2["Execution"] = "execution";
|
|
2414
|
+
WorkflowValidationErrorType2["Stale"] = "stale";
|
|
2415
|
+
return WorkflowValidationErrorType2;
|
|
2416
|
+
})(WorkflowValidationErrorType || {});
|
|
2417
|
+
|
|
2418
|
+
// src/domain/validation/utils.ts
|
|
2419
|
+
var resolveTasksRecursively = (tasks, contexts) => tasks.map((task) => {
|
|
2420
|
+
var _a;
|
|
2421
|
+
const taskContext = contexts.tasks[task.taskReferenceName];
|
|
2422
|
+
const resolveOptions = {
|
|
2423
|
+
noFallback: true,
|
|
2424
|
+
zeroArrayIndex: !taskContext.execution
|
|
2425
|
+
};
|
|
2426
|
+
if (task.type === WorkflowTaskType6.switch) {
|
|
2427
|
+
const resolved = jsonUtils.resolveObjectByContext(
|
|
2428
|
+
{ ...task, decisionCases: {}, defaultCase: [] },
|
|
2429
|
+
taskContext.environment,
|
|
2430
|
+
resolveOptions
|
|
2431
|
+
);
|
|
2432
|
+
return {
|
|
2433
|
+
...resolved != null ? resolved : task,
|
|
2434
|
+
decisionCases: Object.fromEntries(
|
|
2435
|
+
Object.entries(task.decisionCases).map(([caseName, caseTasks]) => [
|
|
2436
|
+
caseName,
|
|
2437
|
+
resolveTasksRecursively(caseTasks, contexts)
|
|
2438
|
+
])
|
|
2439
|
+
),
|
|
2440
|
+
...task.defaultCase ? {
|
|
2441
|
+
defaultCase: resolveTasksRecursively(task.defaultCase, contexts)
|
|
2442
|
+
} : {}
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
if (task.type === WorkflowTaskType6.forkJoin) {
|
|
2446
|
+
const resolved = jsonUtils.resolveObjectByContext(
|
|
2447
|
+
{ ...task, forkTasks: [] },
|
|
2448
|
+
taskContext.environment,
|
|
2449
|
+
resolveOptions
|
|
2450
|
+
);
|
|
2451
|
+
return {
|
|
2452
|
+
...resolved != null ? resolved : task,
|
|
2453
|
+
forkTasks: task.forkTasks.map(
|
|
2454
|
+
(branch) => resolveTasksRecursively(branch, contexts)
|
|
2455
|
+
)
|
|
2456
|
+
};
|
|
2457
|
+
}
|
|
2458
|
+
return (_a = jsonUtils.resolveObjectByContext(
|
|
2459
|
+
task,
|
|
2460
|
+
taskContext.environment,
|
|
2461
|
+
resolveOptions
|
|
2462
|
+
)) != null ? _a : task;
|
|
2463
|
+
});
|
|
2464
|
+
var validateSchema = (workflow, contexts, validateFunction) => {
|
|
2465
|
+
var _a, _b;
|
|
2466
|
+
const resolved = {
|
|
2467
|
+
...workflow,
|
|
2468
|
+
definition: {
|
|
2469
|
+
...workflow.definition,
|
|
2470
|
+
tasks: resolveTasksRecursively(workflow.definition.tasks, contexts)
|
|
2471
|
+
},
|
|
2472
|
+
trigger: jsonUtils.resolveObjectByContext(
|
|
2473
|
+
workflow.trigger,
|
|
2474
|
+
(_a = contexts.trigger) == null ? void 0 : _a.environment,
|
|
2475
|
+
{
|
|
2476
|
+
noFallback: true,
|
|
2477
|
+
zeroArrayIndex: !((_b = contexts.trigger) == null ? void 0 : _b.execution)
|
|
2478
|
+
}
|
|
2479
|
+
)
|
|
2480
|
+
};
|
|
2481
|
+
try {
|
|
2482
|
+
validateFunction(resolved);
|
|
2483
|
+
} catch (error) {
|
|
2484
|
+
if (error instanceof RangeError) {
|
|
2485
|
+
return [];
|
|
2486
|
+
}
|
|
2487
|
+
throw error;
|
|
2488
|
+
}
|
|
2489
|
+
return (validateFunction.errors || []).filter(
|
|
2490
|
+
// Filter out errors that comes from validation of "valid one of possible tasks"
|
|
2491
|
+
// It's need to filter because for dynamic inputs sometimes task doesnt fit format, min/max length etc.
|
|
2492
|
+
(x) => !/^#\/items\/allOf\/[^/]+\/if$/.exec(x.schemaPath)
|
|
2493
|
+
).map((error) => ({
|
|
2494
|
+
...error,
|
|
2495
|
+
severity: "error"
|
|
2496
|
+
}));
|
|
2497
|
+
};
|
|
2498
|
+
function validateCredential(credentialId, taskProvider, credentialPath, credentials) {
|
|
2499
|
+
if (!credentialId) {
|
|
2500
|
+
return [];
|
|
2501
|
+
}
|
|
2502
|
+
const errors = [];
|
|
2503
|
+
const credential = credentials.find((c) => c.name === credentialId);
|
|
2504
|
+
if (!credential) {
|
|
2505
|
+
errors.push({
|
|
2506
|
+
instancePath: credentialPath,
|
|
2507
|
+
keyword: "connection" /* Connection */,
|
|
2508
|
+
message: "Credential not found",
|
|
2509
|
+
params: {},
|
|
2510
|
+
severity: "error"
|
|
2511
|
+
});
|
|
2512
|
+
} else {
|
|
2513
|
+
const expectedProvider = (taskProvider == null ? void 0 : taskProvider.startsWith(IntegrationNames2.Text)) ? IntegrationNames2.Text : taskProvider;
|
|
2514
|
+
if (expectedProvider && taskProvider !== OTHER_TYPES.SYSTEM && credential.provider !== expectedProvider) {
|
|
2515
|
+
errors.push({
|
|
2516
|
+
instancePath: credentialPath,
|
|
2517
|
+
keyword: "connection" /* Connection */,
|
|
2518
|
+
message: `Credential provider mismatch (expected ${expectedProvider}, got ${credential.provider})`,
|
|
2519
|
+
params: {},
|
|
2520
|
+
severity: "error"
|
|
2521
|
+
});
|
|
2522
|
+
}
|
|
2523
|
+
if (credential.type === CredentialType2.OAuth2 && !credential.data.connected) {
|
|
2524
|
+
errors.push({
|
|
2525
|
+
instancePath: credentialPath,
|
|
2526
|
+
keyword: "connection" /* Connection */,
|
|
2527
|
+
message: "Credential is not connected",
|
|
2528
|
+
params: {},
|
|
2529
|
+
severity: "error"
|
|
2530
|
+
});
|
|
2531
|
+
}
|
|
2532
|
+
}
|
|
2533
|
+
return errors;
|
|
2534
|
+
}
|
|
2535
|
+
var getActionFunctionError = (outputData) => {
|
|
2536
|
+
const error = outputData == null ? void 0 : outputData.error;
|
|
2537
|
+
return (error == null ? void 0 : error.type) === "function_error" ? error : void 0;
|
|
2538
|
+
};
|
|
2539
|
+
var validateTasks = (workflow, contexts, credentials, products) => {
|
|
2540
|
+
function taskCompiler(task, baseInstancePath) {
|
|
2541
|
+
var _a, _b, _c;
|
|
2542
|
+
const context = contexts.tasks[task.taskReferenceName];
|
|
2543
|
+
const config = context == null ? void 0 : context.config;
|
|
2544
|
+
const environment = context == null ? void 0 : context.environment;
|
|
2545
|
+
const execution = context == null ? void 0 : context.execution;
|
|
2546
|
+
const resolvingErrors = jsonUtils.getMatchesInObject(task).map((match) => {
|
|
2547
|
+
var _a2, _b2, _c2;
|
|
2548
|
+
const segments = match.rawValue.split(".");
|
|
2549
|
+
let message = "Invalid field value";
|
|
2550
|
+
const params = {};
|
|
2551
|
+
if (!(environment == null ? void 0 : environment[segments[0]])) {
|
|
2552
|
+
if (segments[0]) {
|
|
2553
|
+
if (contexts.tasks[segments[0]]) {
|
|
2554
|
+
message += " - task not accessible";
|
|
2555
|
+
} else {
|
|
2556
|
+
message += " - task not found";
|
|
2557
|
+
}
|
|
2558
|
+
}
|
|
2559
|
+
} else if (segments[0] === "workflow") {
|
|
2560
|
+
if (segments[1] === "input") {
|
|
2561
|
+
const resolved = validatePathAgainstSchema(
|
|
2562
|
+
segments.slice(2).join("."),
|
|
2563
|
+
(_a2 = environment.workflow.input) == null ? void 0 : _a2.__meta.config.specification.output
|
|
2564
|
+
);
|
|
2565
|
+
if (resolved.valid) {
|
|
2566
|
+
return;
|
|
2567
|
+
}
|
|
2568
|
+
if (segments[2] === "body") {
|
|
2569
|
+
if ((_b2 = workflow.trigger) == null ? void 0 : _b2.type) {
|
|
2570
|
+
message += " - invalid trigger property";
|
|
2571
|
+
} else {
|
|
2572
|
+
message += " - trigger not found";
|
|
2573
|
+
}
|
|
2574
|
+
} else if (!((_c2 = workflow.trigger) == null ? void 0 : _c2.type) || workflow.trigger.type === WorkflowTriggerType6.recurring || workflow.trigger.type === WorkflowTriggerType6.webhook) {
|
|
2575
|
+
message = "Couldn't use manual parameters when trigger is not manual";
|
|
2576
|
+
} else {
|
|
2577
|
+
message += " - invalid input property";
|
|
2578
|
+
}
|
|
2579
|
+
} else {
|
|
2580
|
+
message += " - invalid property";
|
|
2581
|
+
}
|
|
2582
|
+
} else {
|
|
2583
|
+
const elementFrame = environment[segments[0]];
|
|
2584
|
+
const resolved = validatePathAgainstSchema(
|
|
2585
|
+
segments.slice(1).join("."),
|
|
2586
|
+
elementFrame == null ? void 0 : elementFrame.__meta.config.specification.output
|
|
2587
|
+
);
|
|
2588
|
+
if (resolved.valid) {
|
|
2589
|
+
if (elementFrame == null ? void 0 : elementFrame.__meta.config.stale) {
|
|
2590
|
+
message += " - stale property used";
|
|
2591
|
+
return {
|
|
2592
|
+
instancePath: `${baseInstancePath}/${match.instancePath}`,
|
|
2593
|
+
keyword: "stale" /* Stale */,
|
|
2594
|
+
message,
|
|
2595
|
+
params,
|
|
2596
|
+
severity: "error"
|
|
2597
|
+
};
|
|
2598
|
+
}
|
|
2599
|
+
return;
|
|
2600
|
+
}
|
|
2601
|
+
message += " - invalid task property";
|
|
2602
|
+
}
|
|
2603
|
+
return {
|
|
2604
|
+
instancePath: `${baseInstancePath}/${match.instancePath}`,
|
|
2605
|
+
keyword: "resolver" /* Resolver */,
|
|
2606
|
+
message,
|
|
2607
|
+
params,
|
|
2608
|
+
severity: "error"
|
|
2609
|
+
};
|
|
2610
|
+
}).filter(Boolean);
|
|
2611
|
+
const actionFunctionError = (execution == null ? void 0 : execution.data.taskType) === WorkflowTaskType6.simple ? getActionFunctionError(execution.data.outputData) : void 0;
|
|
2612
|
+
const executionErrors = (execution == null ? void 0 : execution.data.status) === WorkflowExecutionTaskStatus2.Failed ? [
|
|
2613
|
+
execution.data.taskType === WorkflowTaskType6.http && ((_a = execution.data.outputData.response.body) == null ? void 0 : _a.type) === "function_error" ? execution.data.outputData.response.body.error_type === "unauthorized" ? {
|
|
2614
|
+
instancePath: baseInstancePath,
|
|
2615
|
+
keyword: "execution" /* Execution */,
|
|
2616
|
+
message: execution.data.outputData.response.body.error,
|
|
2617
|
+
params: {},
|
|
2618
|
+
severity: "error"
|
|
2619
|
+
} : {
|
|
2620
|
+
instancePath: execution.data.outputData.response.body.affected_field ? `${baseInstancePath}/inputParameters/http_request/${execution.data.outputData.response.body.affected_field.field_location}/${execution.data.outputData.response.body.affected_field.field_path.replaceAll(
|
|
2621
|
+
".",
|
|
2622
|
+
"/"
|
|
2623
|
+
)}` : baseInstancePath,
|
|
2624
|
+
keyword: "execution" /* Execution */,
|
|
2625
|
+
message: execution.data.outputData.response.body.error,
|
|
2626
|
+
params: {},
|
|
2627
|
+
severity: "error"
|
|
2628
|
+
} : actionFunctionError ? {
|
|
2629
|
+
instancePath: ((_b = actionFunctionError.affected_field) == null ? void 0 : _b.field_path) ? `${baseInstancePath}/inputParameters/${actionFunctionError.affected_field.field_path.replaceAll(
|
|
2630
|
+
".",
|
|
2631
|
+
"/"
|
|
2632
|
+
)}` : baseInstancePath,
|
|
2633
|
+
keyword: "execution" /* Execution */,
|
|
2634
|
+
message: actionFunctionError.error,
|
|
2635
|
+
params: {},
|
|
2636
|
+
severity: "error"
|
|
2637
|
+
} : {
|
|
2638
|
+
instancePath: baseInstancePath,
|
|
2639
|
+
keyword: "execution" /* Execution */,
|
|
2640
|
+
message: execution.data.reasonForIncompletion,
|
|
2641
|
+
params: {},
|
|
2642
|
+
severity: "error"
|
|
2643
|
+
}
|
|
2644
|
+
] : [];
|
|
2645
|
+
const activationError = (config == null ? void 0 : config.customization.provider) !== IntegrationNames2.Text && (config == null ? void 0 : config.customization.provider.startsWith(IntegrationNames2.Text)) && !products.find(
|
|
2646
|
+
({ product }) => product === config.customization.providerDisplay || product === TEXTAPP_PRODUCT_NAME
|
|
2647
|
+
) && {
|
|
2648
|
+
instancePath: baseInstancePath,
|
|
2649
|
+
keyword: "activation" /* Activation */,
|
|
2650
|
+
message: `${config.customization.providerDisplay} not activated`,
|
|
2651
|
+
params: {},
|
|
2652
|
+
severity: "error"
|
|
2653
|
+
};
|
|
2654
|
+
const credentialErrors = task.type === WorkflowTaskType6.http && "http_request" in task.inputParameters ? validateCredential(
|
|
2655
|
+
task.inputParameters.http_request.credentialId,
|
|
2656
|
+
config == null ? void 0 : config.customization.provider,
|
|
2657
|
+
`${baseInstancePath}/inputParameters/http_request/credentialId`,
|
|
2658
|
+
credentials
|
|
2659
|
+
) : [];
|
|
2660
|
+
const staleError = ((_c = context == null ? void 0 : context.introspection) == null ? void 0 : _c.stale) ? {
|
|
2661
|
+
instancePath: baseInstancePath,
|
|
2662
|
+
keyword: "stale" /* Stale */,
|
|
2663
|
+
message: "Task is stale - test it again to refresh its data",
|
|
2664
|
+
params: {},
|
|
2665
|
+
severity: "warning"
|
|
2666
|
+
} : null;
|
|
2667
|
+
return [
|
|
2668
|
+
...resolvingErrors,
|
|
2669
|
+
...executionErrors,
|
|
2670
|
+
...credentialErrors,
|
|
2671
|
+
...activationError ? [activationError] : [],
|
|
2672
|
+
...staleError ? [staleError] : []
|
|
2673
|
+
];
|
|
2674
|
+
}
|
|
2675
|
+
function taskReducer(tasks, initial, baseInstancePath) {
|
|
2676
|
+
return tasks.reduce((result, task, taskIndex) => {
|
|
2677
|
+
const taskBaseInstancePath = `${baseInstancePath}/${taskIndex}`;
|
|
2678
|
+
if (task.type === WorkflowTaskType6.switch) {
|
|
2679
|
+
result.push(
|
|
2680
|
+
...taskCompiler(
|
|
2681
|
+
{
|
|
2682
|
+
...task,
|
|
2683
|
+
decisionCases: {}
|
|
2684
|
+
},
|
|
2685
|
+
taskBaseInstancePath
|
|
2686
|
+
)
|
|
2687
|
+
);
|
|
2688
|
+
return Object.entries(task.decisionCases).reduce(
|
|
2689
|
+
(innerResult, [decisionCase, innerTasks]) => taskReducer(
|
|
2690
|
+
innerTasks,
|
|
2691
|
+
innerResult,
|
|
2692
|
+
`${taskBaseInstancePath}/decisionCases/${decisionCase}`
|
|
2693
|
+
),
|
|
2694
|
+
result
|
|
2695
|
+
);
|
|
2696
|
+
}
|
|
2697
|
+
if (task.type === WorkflowTaskType6.forkJoin) {
|
|
2698
|
+
result.push(
|
|
2699
|
+
...taskCompiler(
|
|
2700
|
+
{
|
|
2701
|
+
...task,
|
|
2702
|
+
forkTasks: []
|
|
2703
|
+
},
|
|
2704
|
+
taskBaseInstancePath
|
|
2705
|
+
)
|
|
2706
|
+
);
|
|
2707
|
+
return task.forkTasks.reduce(
|
|
2708
|
+
(innerResult, innerTasks, branchIndex) => taskReducer(
|
|
2709
|
+
innerTasks,
|
|
2710
|
+
innerResult,
|
|
2711
|
+
`${taskBaseInstancePath}/forkTasks/${branchIndex}`
|
|
2712
|
+
),
|
|
2713
|
+
result
|
|
2714
|
+
);
|
|
2715
|
+
}
|
|
2716
|
+
if (task.type === WorkflowTaskType6.doWhile) {
|
|
2717
|
+
result.push(
|
|
2718
|
+
...taskCompiler(
|
|
2719
|
+
{
|
|
2720
|
+
...task,
|
|
2721
|
+
loopOver: []
|
|
2722
|
+
},
|
|
2723
|
+
taskBaseInstancePath
|
|
2724
|
+
)
|
|
2725
|
+
);
|
|
2726
|
+
const innerErrors = taskReducer(
|
|
2727
|
+
task.loopOver,
|
|
2728
|
+
result,
|
|
2729
|
+
`${taskBaseInstancePath}/loopOver`
|
|
2730
|
+
);
|
|
2731
|
+
return [...result, ...innerErrors];
|
|
2732
|
+
}
|
|
2733
|
+
result.push(...taskCompiler(task, taskBaseInstancePath));
|
|
2734
|
+
return result;
|
|
2735
|
+
}, initial);
|
|
2736
|
+
}
|
|
2737
|
+
return taskReducer(workflow.definition.tasks, [], "/definition/tasks");
|
|
2738
|
+
};
|
|
2739
|
+
var validateTrigger = (trigger, contexts, credentials, products) => {
|
|
2740
|
+
var _a, _b;
|
|
2741
|
+
const config = (_a = contexts.trigger) == null ? void 0 : _a.config;
|
|
2742
|
+
const execution = (_b = contexts.trigger) == null ? void 0 : _b.execution;
|
|
2743
|
+
const resolvingErrors = jsonUtils.getMatchesInObject(trigger).map((match) => {
|
|
2744
|
+
let message = "Invalid field value";
|
|
2745
|
+
const segments = match.rawValue.split(".");
|
|
2746
|
+
const params = {};
|
|
2747
|
+
if (segments[0] === "workflow") {
|
|
2748
|
+
message += " - invalid property";
|
|
2749
|
+
} else {
|
|
2750
|
+
message += " - invalid trigger property";
|
|
2751
|
+
}
|
|
2752
|
+
return {
|
|
2753
|
+
instancePath: `/trigger/${match.instancePath}`,
|
|
2754
|
+
keyword: "resolver" /* Resolver */,
|
|
2755
|
+
message,
|
|
2756
|
+
params,
|
|
2757
|
+
severity: "error"
|
|
2758
|
+
};
|
|
2759
|
+
}).filter(Boolean);
|
|
2760
|
+
const executionErrors = (execution == null ? void 0 : execution.data.status) === WorkflowExecutionTaskStatus2.Failed ? [
|
|
2761
|
+
{
|
|
2762
|
+
instancePath: "/trigger",
|
|
2763
|
+
keyword: "execution" /* Execution */,
|
|
2764
|
+
message: "Trigger execution failed",
|
|
2765
|
+
params: {},
|
|
2766
|
+
severity: "error"
|
|
2767
|
+
}
|
|
2768
|
+
] : [];
|
|
2769
|
+
const activationError = (config == null ? void 0 : config.customization.provider.startsWith(IntegrationNames2.Text)) && !products.find(
|
|
2770
|
+
({ product }) => product === config.customization.providerDisplay || product === TEXTAPP_PRODUCT_NAME
|
|
2771
|
+
) && {
|
|
2772
|
+
instancePath: "/trigger",
|
|
2773
|
+
keyword: "activation" /* Activation */,
|
|
2774
|
+
message: `${config.customization.providerDisplay} not activated`,
|
|
2775
|
+
params: {},
|
|
2776
|
+
severity: "error"
|
|
2777
|
+
};
|
|
2778
|
+
const credentialErrors = trigger.type === WorkflowTriggerType6.webhook ? validateCredential(
|
|
2779
|
+
trigger.webhook.credential_id,
|
|
2780
|
+
config == null ? void 0 : config.customization.provider,
|
|
2781
|
+
"/trigger/webhook/credential_id",
|
|
2782
|
+
credentials
|
|
2783
|
+
) : [];
|
|
2784
|
+
return [
|
|
2785
|
+
...resolvingErrors,
|
|
2786
|
+
...executionErrors,
|
|
2787
|
+
...credentialErrors,
|
|
2788
|
+
...activationError ? [activationError] : []
|
|
2789
|
+
];
|
|
2790
|
+
};
|
|
2791
|
+
function flattenErrorSchema(workflow, schema) {
|
|
2792
|
+
var _a, _b;
|
|
2793
|
+
function cutoffNestedErrors(errorObj) {
|
|
2794
|
+
if (!errorObj) return void 0;
|
|
2795
|
+
const entries = Object.entries(errorObj).map(([key, value]) => {
|
|
2796
|
+
if (key.startsWith("__")) return [key, value];
|
|
2797
|
+
const item = value;
|
|
2798
|
+
return item.__errors ? [
|
|
2799
|
+
key,
|
|
2800
|
+
{
|
|
2801
|
+
__errors: item.__errors,
|
|
2802
|
+
__errorsExtended: item.__errorsExtended
|
|
2803
|
+
}
|
|
2804
|
+
] : null;
|
|
2805
|
+
}).filter(Boolean);
|
|
2806
|
+
return entries.length > 0 ? Object.fromEntries(entries) : void 0;
|
|
2807
|
+
}
|
|
2808
|
+
function processContainerTask(result, task, nestedGroups, nestedErrorGroups, containerErrors, nestedFieldName) {
|
|
2809
|
+
const final = nestedGroups.reduce(
|
|
2810
|
+
(acc, tasks, i) => flattenTaskErrors(tasks, {
|
|
2811
|
+
tasksErrors: acc.tasksErrors,
|
|
2812
|
+
errors: nestedErrorGroups[i]
|
|
2813
|
+
}),
|
|
2814
|
+
result
|
|
2815
|
+
);
|
|
2816
|
+
if (containerErrors) {
|
|
2817
|
+
const cutoff = cutoffNestedErrors(
|
|
2818
|
+
containerErrors[nestedFieldName]
|
|
2819
|
+
);
|
|
2820
|
+
const cutoffErrors = {
|
|
2821
|
+
...containerErrors,
|
|
2822
|
+
[nestedFieldName]: cutoff
|
|
2823
|
+
};
|
|
2824
|
+
const allErrors = collectAllErrors(
|
|
2825
|
+
cutoffErrors
|
|
2826
|
+
);
|
|
2827
|
+
if (allErrors.length > 0) {
|
|
2828
|
+
final.tasksErrors[task.taskReferenceName] = cutoffErrors;
|
|
2829
|
+
final.tasksErrors[task.taskReferenceName].__allErrors = allErrors;
|
|
2830
|
+
}
|
|
2831
|
+
}
|
|
2832
|
+
return { tasksErrors: final.tasksErrors, errors: result.errors };
|
|
2833
|
+
}
|
|
2834
|
+
function flattenTaskErrors(tasks, initial) {
|
|
2835
|
+
return tasks.reduce((result, task, taskIndex) => {
|
|
2836
|
+
var _a2;
|
|
2837
|
+
const taskErrorsSchema = (_a2 = result.errors) == null ? void 0 : _a2[taskIndex];
|
|
2838
|
+
if (task.type === WorkflowTaskType6.switch) {
|
|
2839
|
+
const switchErrors = taskErrorsSchema;
|
|
2840
|
+
return processContainerTask(
|
|
2841
|
+
result,
|
|
2842
|
+
task,
|
|
2843
|
+
Object.values(task.decisionCases),
|
|
2844
|
+
Object.keys(task.decisionCases).map(
|
|
2845
|
+
(key) => {
|
|
2846
|
+
var _a3;
|
|
2847
|
+
return (_a3 = switchErrors == null ? void 0 : switchErrors.decisionCases) == null ? void 0 : _a3[key];
|
|
2848
|
+
}
|
|
2849
|
+
),
|
|
2850
|
+
switchErrors,
|
|
2851
|
+
"decisionCases"
|
|
2852
|
+
);
|
|
2853
|
+
}
|
|
2854
|
+
if (task.type === WorkflowTaskType6.forkJoin) {
|
|
2855
|
+
const forkErrors = taskErrorsSchema;
|
|
2856
|
+
return processContainerTask(
|
|
2857
|
+
result,
|
|
2858
|
+
task,
|
|
2859
|
+
task.forkTasks,
|
|
2860
|
+
task.forkTasks.map((_, i) => {
|
|
2861
|
+
var _a3;
|
|
2862
|
+
return (_a3 = forkErrors == null ? void 0 : forkErrors.forkTasks) == null ? void 0 : _a3[i];
|
|
2863
|
+
}),
|
|
2864
|
+
forkErrors,
|
|
2865
|
+
"forkTasks"
|
|
2866
|
+
);
|
|
2867
|
+
}
|
|
2868
|
+
if (task.type === WorkflowTaskType6.doWhile) {
|
|
2869
|
+
const loopErrors = taskErrorsSchema;
|
|
2870
|
+
return processContainerTask(
|
|
2871
|
+
result,
|
|
2872
|
+
task,
|
|
2873
|
+
[task.loopOver],
|
|
2874
|
+
[loopErrors == null ? void 0 : loopErrors.loopOver],
|
|
2875
|
+
loopErrors,
|
|
2876
|
+
"loopOver"
|
|
2877
|
+
);
|
|
2878
|
+
}
|
|
2879
|
+
if (taskErrorsSchema) {
|
|
2880
|
+
const allErrors = collectAllErrors(taskErrorsSchema);
|
|
2881
|
+
result.tasksErrors[task.taskReferenceName] = taskErrorsSchema;
|
|
2882
|
+
result.tasksErrors[task.taskReferenceName].__allErrors = allErrors;
|
|
2883
|
+
}
|
|
2884
|
+
return result;
|
|
2885
|
+
}, initial);
|
|
2886
|
+
}
|
|
2887
|
+
const { tasksErrors } = flattenTaskErrors(workflow.definition.tasks, {
|
|
2888
|
+
errors: (_a = schema.definition) == null ? void 0 : _a.tasks,
|
|
2889
|
+
tasksErrors: {}
|
|
2890
|
+
});
|
|
2891
|
+
return Object.fromEntries(
|
|
2892
|
+
Object.entries({
|
|
2893
|
+
trigger: schema.trigger ? {
|
|
2894
|
+
...schema.trigger,
|
|
2895
|
+
__allErrors: collectAllErrors(schema.trigger)
|
|
2896
|
+
} : void 0,
|
|
2897
|
+
tasks: tasksErrors,
|
|
2898
|
+
all: {
|
|
2899
|
+
...tasksErrors,
|
|
2900
|
+
...((_b = workflow.trigger) == null ? void 0 : _b.name) ? { [workflow.trigger.name]: schema.trigger } : {}
|
|
2901
|
+
}
|
|
2902
|
+
}).filter(([, value]) => Boolean(value))
|
|
2903
|
+
);
|
|
2904
|
+
}
|
|
2905
|
+
var getWorkflowValidation = (workflow, internal, external, validator) => {
|
|
2906
|
+
var _a;
|
|
2907
|
+
const rawErrors = [
|
|
2908
|
+
...((_a = workflow.trigger) == null ? void 0 : _a.type) ? validateTrigger(
|
|
2909
|
+
workflow.trigger,
|
|
2910
|
+
internal.contexts,
|
|
2911
|
+
internal.credentials,
|
|
2912
|
+
external.products
|
|
2913
|
+
) : [],
|
|
2914
|
+
...validateTasks(
|
|
2915
|
+
workflow,
|
|
2916
|
+
internal.contexts,
|
|
2917
|
+
internal.credentials,
|
|
2918
|
+
external.products
|
|
2919
|
+
),
|
|
2920
|
+
...validateSchema(workflow, internal.contexts, validator)
|
|
2921
|
+
];
|
|
2922
|
+
const schema = buildErrorSchema(rawErrors, workflow);
|
|
2923
|
+
const errors = flattenErrorSchema(workflow, schema);
|
|
2924
|
+
return {
|
|
2925
|
+
isValid: !Object.values(schema).length,
|
|
2926
|
+
raw: schema,
|
|
2927
|
+
errors
|
|
2928
|
+
};
|
|
2929
|
+
};
|
|
2930
|
+
|
|
2931
|
+
// src/domain/validation/index.ts
|
|
2932
|
+
var schemaValidator;
|
|
2933
|
+
function validateWorkflow(workflow, sources, dependencies) {
|
|
2934
|
+
var _a;
|
|
2935
|
+
schemaValidator != null ? schemaValidator : schemaValidator = getValidator(workflowSchema);
|
|
2936
|
+
const specification = (_a = dependencies.specification) != null ? _a : getSpecification();
|
|
2937
|
+
const contexts = getWorkflowContexts(workflow, sources, { specification });
|
|
2938
|
+
return getWorkflowValidation(
|
|
2939
|
+
workflow,
|
|
2940
|
+
{
|
|
2941
|
+
contexts,
|
|
2942
|
+
credentials: getWorkflowCredentials(dependencies.credentials)
|
|
2943
|
+
},
|
|
2944
|
+
{ products: dependencies.products },
|
|
2945
|
+
schemaValidator
|
|
2946
|
+
);
|
|
2947
|
+
}
|
|
2948
|
+
|
|
2949
|
+
// src/domain/index.ts
|
|
2950
|
+
export * from "@livechat/developer-studio-api/workflow-contracts";
|
|
2951
|
+
import { IntegrationNames as IntegrationNames3 } from "@livechat/developer-studio-api";
|
|
2952
|
+
export {
|
|
2953
|
+
IntegrationNames3 as IntegrationNames,
|
|
2954
|
+
WorkflowElementActionType,
|
|
2955
|
+
WorkflowValidationErrorType,
|
|
2956
|
+
applyChange,
|
|
2957
|
+
applyDefaultCredentials,
|
|
2958
|
+
applyWorkflowAssetBindings,
|
|
2959
|
+
buildWorkflowFromLight,
|
|
2960
|
+
createFrameReference,
|
|
2961
|
+
createFrameReferenceByContext,
|
|
2962
|
+
createFrameReferenceByEnvironment,
|
|
2963
|
+
getTaskAssets,
|
|
2964
|
+
getTriggerAssets,
|
|
2965
|
+
getWorkflowContexts,
|
|
2966
|
+
getWorkflowCredentials,
|
|
2967
|
+
getWorkflowElementConfig,
|
|
2968
|
+
getWorkflowElementDefaultCredentialId,
|
|
2969
|
+
getWorkflowTaskActions,
|
|
2970
|
+
mergeAssets,
|
|
2971
|
+
prefillWorkflow,
|
|
2972
|
+
recursiveTaskReducer,
|
|
2973
|
+
reduceTasksRecursively,
|
|
2974
|
+
validateWorkflow
|
|
2975
|
+
};
|