@oomol-lab/open-flow 0.1.0-beta.80 → 0.1.0-beta.82
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/README.md +35 -0
- package/dist/browser/{FlowCanvas-CrsiDHK8.js → FlowCanvas-Dew2fmoT.js} +55 -274
- package/dist/browser/{createResourceDialog-CS3u9ga9.js → createResourceDialog-bdOJa5Zk.js} +2 -1
- package/dist/browser/{exportPng-BOPfjeEi.js → exportPng-Cjdb6COo.js} +2 -2
- package/dist/browser/{flowChanges-pFjPHU5k.js → flowChanges-URBEd4DI.js} +2719 -78
- package/dist/browser/{flowWorkspace-CRlqc403.js → flowWorkspace-BlXx-yAn.js} +445 -2699
- package/dist/browser/{markdownContent-CAG_CQfH.js → markdownContent-D8G_oNOe.js} +18 -41
- package/dist/browser/{markdownContent-frwDfQQU.js → markdownContent-IS8xXDoc.js} +18 -40
- package/dist/browser/preview.css +88 -80
- package/dist/browser/preview.js +291 -188
- package/dist/browser/ui.css +8 -0
- package/dist/browser/{dist-CHwj9BhV.js → videoLink-NAWDmBtf.js} +35 -1
- package/dist/browser/workbench-contract.d.ts +6 -0
- package/dist/browser/workbench.css +259 -251
- package/dist/browser/workbench.d.ts +2 -0
- package/dist/browser/workbench.js +311 -143
- package/dist/browser/{ContentIcon-CMn0c-kl.js → wrapLayout-DZvW9dBs.js} +4397 -4152
- package/dist/command/index.js +43 -41
- package/dist/common/authoring.d.ts +1 -1
- package/dist/common/control-api-conformance.js +306 -2
- package/dist/common/control-api.d.ts +20 -0
- package/dist/common/control-api.js +306 -4
- package/dist/common/control-requests.d.ts +3 -5
- package/dist/common/control-requests.js +24 -10
- package/dist/common/flow-authoring.js +19 -3
- package/dist/common/flow-encoding.d.ts +1 -0
- package/dist/common/flow-encoding.js +167 -1
- package/dist/common/flow-semantics.js +44 -7
- package/dist/common/flow-workflowBundle.d.ts +27 -0
- package/dist/common/flow-workflowFile.d.ts +2 -0
- package/dist/common/flow-workflowReferences.d.ts +4 -0
- package/dist/common/mcp.d.ts +2 -0
- package/dist/common/mcp.js +312 -4
- package/dist/render/browser/licenses.md +4047 -0
- package/dist/render/browser/runtime.css +14877 -0
- package/dist/render/browser/runtime.js +266765 -0
- package/dist/render/common/png.d.ts +24 -0
- package/dist/render/node/index.d.ts +11 -0
- package/dist/render/node/index.js +9491 -0
- package/dist/render/node/licenses.md +75 -0
- package/package.json +12 -2
- package/src/connector/common/actionContract.ts +26 -0
- package/src/control/common/api.ts +50 -0
- package/src/control/common/flowDecoders.ts +2 -0
- package/src/control/common/mcp.ts +4 -4
- package/src/control/common/requests.ts +12 -1
- package/src/flow/common/edgeChanges.ts +9 -6
- package/src/flow/common/encoding.ts +1 -0
- package/src/flow/common/semantics.ts +11 -8
- package/src/flow/common/workflowBundle.ts +117 -0
- package/src/flow/common/workflowFile.ts +4 -0
- package/src/flow/common/workflowReferences.ts +20 -0
|
@@ -8617,6 +8617,31 @@ function isSchemaKeyword(value) {
|
|
|
8617
8617
|
return schemaKeywords.has(value);
|
|
8618
8618
|
}
|
|
8619
8619
|
//#endregion
|
|
8620
|
+
//#region src/flow/common/workflowReferences.ts
|
|
8621
|
+
/** Workflow declarations share discovery across authoring, admission and resource indexing. */
|
|
8622
|
+
function nodeWorkflowReferences(node) {
|
|
8623
|
+
if (node.kind != "task") return [];
|
|
8624
|
+
if ("moduleId" in node.task) return (node.task.capabilities ?? []).flatMap((item, index) => item.kind == "workflow" ? [{
|
|
8625
|
+
target: item,
|
|
8626
|
+
path: `task/capabilities/${index}`,
|
|
8627
|
+
tool: item.name
|
|
8628
|
+
}] : []);
|
|
8629
|
+
if (node.task.executor.kind == "workflow") return [{
|
|
8630
|
+
target: {
|
|
8631
|
+
...node.task.executor,
|
|
8632
|
+
inputs: node.task.inputs.filter((port) => "handle" in port),
|
|
8633
|
+
outputs: node.task.outputs.filter((port) => "handle" in port)
|
|
8634
|
+
},
|
|
8635
|
+
path: "task/executor"
|
|
8636
|
+
}];
|
|
8637
|
+
if (node.task.executor.kind == "agent") return node.task.executor.tools.flatMap((item, index) => item.kind == "workflow" ? [{
|
|
8638
|
+
target: item,
|
|
8639
|
+
path: `task/executor/tools/${index}`,
|
|
8640
|
+
tool: item.name
|
|
8641
|
+
}] : []);
|
|
8642
|
+
return [];
|
|
8643
|
+
}
|
|
8644
|
+
//#endregion
|
|
8620
8645
|
//#region src/workflow/common/workflow.ts
|
|
8621
8646
|
var portSchema = object({
|
|
8622
8647
|
handle: string$1().min(1),
|
|
@@ -10547,7 +10572,7 @@ var entrySchema = discriminatedUnion("type", [
|
|
|
10547
10572
|
/** Project only the selected published definition and its current bindings. */
|
|
10548
10573
|
function liveEntries(content, current, bindings) {
|
|
10549
10574
|
const byNode = new Map(bindings.filter((item) => item.flowId == current.flowId && item.currentPublicationId == current.publicationId && item.currentRevisionId == current.revisionId).map((item) => [item.triggerNodeId, item]));
|
|
10550
|
-
return decodeEntries(Object.entries(content.document.graph.nodes).toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).flatMap(([nodeId, node]) => {
|
|
10575
|
+
return decodeEntries$1(Object.entries(content.document.graph.nodes).toSorted(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).flatMap(([nodeId, node]) => {
|
|
10551
10576
|
if (node.kind != "start" && node.kind != "manual" && node.kind != "webhook" && node.kind != "cron" && node.kind != "error" && node.kind != "poll" && node.kind != "integration") return [];
|
|
10552
10577
|
const config = triggerConfiguration(node);
|
|
10553
10578
|
return [{
|
|
@@ -10595,12 +10620,12 @@ function decodeLiveDetails(value) {
|
|
|
10595
10620
|
publication: current,
|
|
10596
10621
|
status,
|
|
10597
10622
|
enabled: source.enabled,
|
|
10598
|
-
entries: decodeEntries(source.entries, current),
|
|
10623
|
+
entries: decodeEntries$1(source.entries, current),
|
|
10599
10624
|
version: 1
|
|
10600
10625
|
};
|
|
10601
10626
|
}
|
|
10602
10627
|
/** Both producers and consumers enforce the same published-entry invariants. */
|
|
10603
|
-
function decodeEntries(values, current) {
|
|
10628
|
+
function decodeEntries$1(values, current) {
|
|
10604
10629
|
const parsed = array(entrySchema).safeParse(values);
|
|
10605
10630
|
if (!parsed.success) return invalidResponse();
|
|
10606
10631
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -10670,17 +10695,134 @@ function conditionInputPorts(node) {
|
|
|
10670
10695
|
nullable: operand.kind === "value" ? operand.value === null : true
|
|
10671
10696
|
}]));
|
|
10672
10697
|
}
|
|
10698
|
+
function clearConditionBinding(operand) {
|
|
10699
|
+
return operand.kind == "source" && operand.source.kind == "binding" ? { kind: "value" } : operand;
|
|
10700
|
+
}
|
|
10701
|
+
function clearConditionBindings(node) {
|
|
10702
|
+
return {
|
|
10703
|
+
...node,
|
|
10704
|
+
cases: node.cases.map((item) => ({
|
|
10705
|
+
...item,
|
|
10706
|
+
groups: item.groups.map((group) => ({
|
|
10707
|
+
...group,
|
|
10708
|
+
expressions: group.expressions.map((expression) => ({
|
|
10709
|
+
...expression,
|
|
10710
|
+
left: clearConditionBinding(expression.left),
|
|
10711
|
+
...expression.right == null ? {} : { right: clearConditionBinding(expression.right) }
|
|
10712
|
+
}))
|
|
10713
|
+
}))
|
|
10714
|
+
}))
|
|
10715
|
+
};
|
|
10716
|
+
}
|
|
10673
10717
|
//#endregion
|
|
10674
10718
|
//#region src/flow/common/model.ts
|
|
10675
10719
|
function portsByHandle(ports) {
|
|
10676
10720
|
return Object.fromEntries(ports.flatMap((port) => "handle" in port ? [[port.handle, port]] : []));
|
|
10677
10721
|
}
|
|
10678
10722
|
//#endregion
|
|
10723
|
+
//#region src/trigger/common/config.ts
|
|
10724
|
+
/** Deployment-bound selections owned by the Trigger configuration contract. */
|
|
10725
|
+
function clearTriggerExternalConfig(key, config) {
|
|
10726
|
+
const fields = key == "jira.on_issue_event" || key == "intercom.on_conversation_event" || key == "sentry.on_issue_alert" || key == "zoom.on_recording_ready" || key == "fireflies.on_meeting_ready" ? ["sourceId", "eventTypes"] : key == "slackbot.on_event" ? [
|
|
10727
|
+
"sourceId",
|
|
10728
|
+
"eventTypes",
|
|
10729
|
+
"channelIds"
|
|
10730
|
+
] : key == "feishu_app_bot.on_event" ? [
|
|
10731
|
+
"sourceId",
|
|
10732
|
+
"eventTypes",
|
|
10733
|
+
"resource",
|
|
10734
|
+
"chatIds"
|
|
10735
|
+
] : key == "linear.on_issue_changed" ? ["teamId", "stateIds"] : [];
|
|
10736
|
+
return {
|
|
10737
|
+
...config,
|
|
10738
|
+
...Object.fromEntries(fields.map((field) => [field, { kind: "unset" }]))
|
|
10739
|
+
};
|
|
10740
|
+
}
|
|
10741
|
+
//#endregion
|
|
10742
|
+
//#region src/flow/common/connectionUsage.ts
|
|
10743
|
+
function clearNodeConnections(graph, connectionId) {
|
|
10744
|
+
return {
|
|
10745
|
+
...graph,
|
|
10746
|
+
nodes: Object.fromEntries(Object.entries(graph.nodes).map(([id, node]) => {
|
|
10747
|
+
if ((node.kind == "poll" || node.kind == "integration") && (connectionId == null || node.connectionId == connectionId)) {
|
|
10748
|
+
const { connectionId: _, ...remaining } = node;
|
|
10749
|
+
return [id, remaining];
|
|
10750
|
+
}
|
|
10751
|
+
if (node.kind != "task") return [id, node];
|
|
10752
|
+
if ("executor" in node.task) {
|
|
10753
|
+
const executor = node.task.executor;
|
|
10754
|
+
const clear = (value) => {
|
|
10755
|
+
if (value.connectionId === "") return value;
|
|
10756
|
+
if (connectionId != null && value.connectionId != connectionId) return value;
|
|
10757
|
+
const { connectionId: _, ...rest } = value;
|
|
10758
|
+
return rest;
|
|
10759
|
+
};
|
|
10760
|
+
if (executor.kind == "connector") return [id, {
|
|
10761
|
+
...node,
|
|
10762
|
+
task: {
|
|
10763
|
+
...node.task,
|
|
10764
|
+
executor: clear(executor)
|
|
10765
|
+
}
|
|
10766
|
+
}];
|
|
10767
|
+
if (executor.kind == "agent") return [id, {
|
|
10768
|
+
...node,
|
|
10769
|
+
task: {
|
|
10770
|
+
...node.task,
|
|
10771
|
+
executor: {
|
|
10772
|
+
...executor,
|
|
10773
|
+
tools: executor.tools.map(clear),
|
|
10774
|
+
...executor.notification == null ? {} : { notification: clear(executor.notification) }
|
|
10775
|
+
}
|
|
10776
|
+
}
|
|
10777
|
+
}];
|
|
10778
|
+
return [id, node];
|
|
10779
|
+
}
|
|
10780
|
+
const capabilities = node.task.capabilities?.map((capability) => {
|
|
10781
|
+
if (capability.kind == "workflow" || capability.kind == "http") return capability;
|
|
10782
|
+
if (!("mode" in capability)) {
|
|
10783
|
+
if ("action" in capability) {
|
|
10784
|
+
const { connectionId: selected, ...rest } = capability;
|
|
10785
|
+
return {
|
|
10786
|
+
...rest,
|
|
10787
|
+
connections: capability.connections.filter((item) => connectionId != null && item.connectionId != connectionId),
|
|
10788
|
+
...selected != null && connectionId != null && selected != connectionId ? { connectionId: selected } : {}
|
|
10789
|
+
};
|
|
10790
|
+
}
|
|
10791
|
+
return {
|
|
10792
|
+
...capability,
|
|
10793
|
+
...connectionId == null && (capability.connectionHints?.length ?? 0) > 0 ? { actionHints: [.../* @__PURE__ */ new Set([...capability.actionHints ?? [], ...capability.connectionHints.map((hint) => hint.action)])] } : {},
|
|
10794
|
+
...capability.connectionHints == null ? {} : { connectionHints: capability.connectionHints.filter((item) => connectionId != null && item.connectionId != connectionId) }
|
|
10795
|
+
};
|
|
10796
|
+
}
|
|
10797
|
+
if (capability.mode != "independent") return capability;
|
|
10798
|
+
return {
|
|
10799
|
+
...capability,
|
|
10800
|
+
actions: capability.actions.map((action) => {
|
|
10801
|
+
if (action.connectionId === "") return action;
|
|
10802
|
+
if (connectionId != null && action.connectionId != connectionId) return action;
|
|
10803
|
+
const { connectionId: _, ...remaining } = action;
|
|
10804
|
+
return remaining;
|
|
10805
|
+
})
|
|
10806
|
+
};
|
|
10807
|
+
});
|
|
10808
|
+
return [id, capabilities == null ? node : {
|
|
10809
|
+
...node,
|
|
10810
|
+
task: {
|
|
10811
|
+
...node.task,
|
|
10812
|
+
capabilities
|
|
10813
|
+
}
|
|
10814
|
+
}];
|
|
10815
|
+
}))
|
|
10816
|
+
};
|
|
10817
|
+
}
|
|
10818
|
+
//#endregion
|
|
10679
10819
|
//#region src/flow/common/workflowFile.ts
|
|
10680
10820
|
var envelope = strictObject({
|
|
10681
10821
|
kind: literal("open-flow-workflow"),
|
|
10682
10822
|
version: literal(1),
|
|
10683
10823
|
name: string$1().optional(),
|
|
10824
|
+
icon: string$1().optional(),
|
|
10825
|
+
description: string$1().optional(),
|
|
10684
10826
|
content: unknown(),
|
|
10685
10827
|
presentation: record$2(string$1(), json$3()).optional()
|
|
10686
10828
|
});
|
|
@@ -10693,6 +10835,126 @@ function decodeWorkflowFile(value) {
|
|
|
10693
10835
|
content: decodeRevisionContent(file.content)
|
|
10694
10836
|
};
|
|
10695
10837
|
}
|
|
10838
|
+
function cleanInput(input) {
|
|
10839
|
+
if (input.kind != "sources" || !input.sources.some((source) => source.kind == "binding")) return input;
|
|
10840
|
+
const sources = input.sources.filter((source) => source.kind != "binding");
|
|
10841
|
+
return sources.length == 0 ? { kind: "unset" } : {
|
|
10842
|
+
kind: "sources",
|
|
10843
|
+
sources
|
|
10844
|
+
};
|
|
10845
|
+
}
|
|
10846
|
+
/** Clear only owned structured references, never strings in code or business values. */
|
|
10847
|
+
function cleanWorkflowFile(value) {
|
|
10848
|
+
const file = decodeWorkflowFile(value);
|
|
10849
|
+
const original = file.content.document.graph;
|
|
10850
|
+
const graph = clearNodeConnections(original);
|
|
10851
|
+
const nodes = Object.fromEntries(Object.entries(graph.nodes).map(([id, source]) => {
|
|
10852
|
+
let node = source;
|
|
10853
|
+
if ("inputs" in node) node = {
|
|
10854
|
+
...node,
|
|
10855
|
+
inputs: Object.fromEntries(Object.entries(node.inputs).map(([key, input]) => [key, cleanInput(input)]))
|
|
10856
|
+
};
|
|
10857
|
+
if (node.kind == "outputs") node = {
|
|
10858
|
+
...node,
|
|
10859
|
+
outputMappings: Object.fromEntries(Object.entries(node.outputMappings).map(([key, input]) => [key, cleanInput(input)]))
|
|
10860
|
+
};
|
|
10861
|
+
if (node.kind == "condition") node = clearConditionBindings(node);
|
|
10862
|
+
if (node.kind == "error" && node.sourceFlowIds != null) node = {
|
|
10863
|
+
...node,
|
|
10864
|
+
sourceFlowIds: []
|
|
10865
|
+
};
|
|
10866
|
+
if (node.kind == "poll" || node.kind == "integration") node = {
|
|
10867
|
+
...node,
|
|
10868
|
+
config: clearTriggerExternalConfig(node.definition.key, node.config)
|
|
10869
|
+
};
|
|
10870
|
+
return [id, node];
|
|
10871
|
+
}));
|
|
10872
|
+
return {
|
|
10873
|
+
file: {
|
|
10874
|
+
...file,
|
|
10875
|
+
content: {
|
|
10876
|
+
...file.content,
|
|
10877
|
+
document: {
|
|
10878
|
+
...file.content.document,
|
|
10879
|
+
bindings: {},
|
|
10880
|
+
graph: {
|
|
10881
|
+
...graph,
|
|
10882
|
+
nodes
|
|
10883
|
+
}
|
|
10884
|
+
}
|
|
10885
|
+
}
|
|
10886
|
+
},
|
|
10887
|
+
summary: {
|
|
10888
|
+
changedNodeIds: Object.keys(nodes).filter((id) => !dequal(nodes[id], original.nodes[id])),
|
|
10889
|
+
removedBindings: Object.keys(file.content.document.bindings).length
|
|
10890
|
+
}
|
|
10891
|
+
};
|
|
10892
|
+
}
|
|
10893
|
+
//#endregion
|
|
10894
|
+
//#region src/flow/common/workflowBundle.ts
|
|
10895
|
+
var entries = array(strictObject({
|
|
10896
|
+
flowId: string$1().min(1),
|
|
10897
|
+
file: unknown()
|
|
10898
|
+
})).min(1);
|
|
10899
|
+
var bundleSchema = strictObject({
|
|
10900
|
+
kind: literal("open-flow-workflow-bundle"),
|
|
10901
|
+
version: literal(1),
|
|
10902
|
+
entryFlowId: string$1().min(1),
|
|
10903
|
+
workflows: entries
|
|
10904
|
+
});
|
|
10905
|
+
var previewSchema = strictObject({
|
|
10906
|
+
version: literal(1),
|
|
10907
|
+
entryFlowId: string$1().min(1),
|
|
10908
|
+
workflows: entries,
|
|
10909
|
+
unavailableFlowIds: array(string$1().min(1))
|
|
10910
|
+
});
|
|
10911
|
+
function decodeEntries(value, entryFlowId, unavailableFlowIds = []) {
|
|
10912
|
+
const workflows = value.map(({ flowId, file }) => ({
|
|
10913
|
+
flowId,
|
|
10914
|
+
file: decodeWorkflowFile(file)
|
|
10915
|
+
}));
|
|
10916
|
+
const ids = new Set(workflows.map(({ flowId }) => flowId));
|
|
10917
|
+
if (ids.size != workflows.length || !ids.has(entryFlowId)) throw new TypeError("Workflow identities must be unique and include the entry workflow.");
|
|
10918
|
+
const unavailable = new Set(unavailableFlowIds);
|
|
10919
|
+
if (unavailable.size != unavailableFlowIds.length || unavailableFlowIds.some((id) => ids.has(id))) throw new TypeError("Invalid unavailable workflow identities.");
|
|
10920
|
+
for (const { file } of workflows) for (const node of Object.values(file.content.document.graph.nodes)) for (const { target } of nodeWorkflowReferences(node)) if (target.flowId && !ids.has(target.flowId) && !unavailable.has(target.flowId)) throw new TypeError("A referenced workflow is missing from the bundle.");
|
|
10921
|
+
return workflows;
|
|
10922
|
+
}
|
|
10923
|
+
function decodeWorkflowBundle(value) {
|
|
10924
|
+
checkJsonDepth(value, -4);
|
|
10925
|
+
const bundle = bundleSchema.parse(value);
|
|
10926
|
+
return {
|
|
10927
|
+
...bundle,
|
|
10928
|
+
workflows: decodeEntries(bundle.workflows, bundle.entryFlowId)
|
|
10929
|
+
};
|
|
10930
|
+
}
|
|
10931
|
+
function decodeWorkflowExportPreview(value) {
|
|
10932
|
+
checkJsonDepth(value, -4);
|
|
10933
|
+
const preview = previewSchema.parse(value);
|
|
10934
|
+
return {
|
|
10935
|
+
...preview,
|
|
10936
|
+
workflows: decodeEntries(preview.workflows, preview.entryFlowId, preview.unavailableFlowIds)
|
|
10937
|
+
};
|
|
10938
|
+
}
|
|
10939
|
+
function cleanWorkflowBundle(value) {
|
|
10940
|
+
const bundle = decodeWorkflowBundle(value);
|
|
10941
|
+
return {
|
|
10942
|
+
...bundle,
|
|
10943
|
+
workflows: bundle.workflows.map(({ flowId, file }) => ({
|
|
10944
|
+
flowId,
|
|
10945
|
+
file: cleanWorkflowFile(file).file
|
|
10946
|
+
}))
|
|
10947
|
+
};
|
|
10948
|
+
}
|
|
10949
|
+
function workflowBundleFromPreview(preview) {
|
|
10950
|
+
if (preview.unavailableFlowIds.length) throw new TypeError("Some referenced workflows are unavailable.");
|
|
10951
|
+
return cleanWorkflowBundle({
|
|
10952
|
+
kind: "open-flow-workflow-bundle",
|
|
10953
|
+
version: 1,
|
|
10954
|
+
entryFlowId: preview.entryFlowId,
|
|
10955
|
+
workflows: preview.workflows
|
|
10956
|
+
});
|
|
10957
|
+
}
|
|
10696
10958
|
//#endregion
|
|
10697
10959
|
//#region src/flow/common/encoding.ts
|
|
10698
10960
|
var encoder$1 = new TextEncoder();
|
|
@@ -11996,6 +12258,8 @@ function flow(value) {
|
|
|
11996
12258
|
resourceReferences: resourceReferences(source.resourceReferences),
|
|
11997
12259
|
flowId: string(source.flowId),
|
|
11998
12260
|
name: string(source.name),
|
|
12261
|
+
...source.icon === void 0 ? {} : { icon: string(source.icon) },
|
|
12262
|
+
...source.description === void 0 ? {} : { description: string(source.description) },
|
|
11999
12263
|
status,
|
|
12000
12264
|
updatedAt: string(source.updatedAt),
|
|
12001
12265
|
version: 1
|
|
@@ -12482,6 +12746,18 @@ function decodeTagListItem(value) {
|
|
|
12482
12746
|
}
|
|
12483
12747
|
//#endregion
|
|
12484
12748
|
//#region src/control/common/api.ts
|
|
12749
|
+
function decodeWorkflowBundleImportResult(value) {
|
|
12750
|
+
const source = record(value);
|
|
12751
|
+
if (source.version != 1 || !Array.isArray(source.flows) || source.flows.length == 0) return invalidResponse();
|
|
12752
|
+
const entry = flow(source.flow);
|
|
12753
|
+
const flows = source.flows.map(flow);
|
|
12754
|
+
if (new Set(flows.map((item) => item.flowId)).size != flows.length || !flows.some((item) => item.flowId == entry.flowId)) return invalidResponse();
|
|
12755
|
+
return {
|
|
12756
|
+
version: 1,
|
|
12757
|
+
flow: entry,
|
|
12758
|
+
flows
|
|
12759
|
+
};
|
|
12760
|
+
}
|
|
12485
12761
|
function isRunTerminalEvent(event) {
|
|
12486
12762
|
return event?.kind == "run.completed" || event?.kind == "run.failed" || event?.kind == "run.canceled" || event?.kind == "run.indeterminate";
|
|
12487
12763
|
}
|
|
@@ -12799,6 +13075,32 @@ var ControlClient = class {
|
|
|
12799
13075
|
return invalidResponse();
|
|
12800
13076
|
}
|
|
12801
13077
|
}
|
|
13078
|
+
async getFlowExportPreview(flowId) {
|
|
13079
|
+
const value = await this.request(`/v1/flows/${segment(flowId)}/export-preview`);
|
|
13080
|
+
try {
|
|
13081
|
+
return decodeWorkflowExportPreview(value);
|
|
13082
|
+
} catch {
|
|
13083
|
+
return invalidResponse();
|
|
13084
|
+
}
|
|
13085
|
+
}
|
|
13086
|
+
async exportFlowBundle(flowId) {
|
|
13087
|
+
const preview = await this.getFlowExportPreview(flowId);
|
|
13088
|
+
if (preview.unavailableFlowIds.length) throw new ApiError(400, "flow.invalid", "Some referenced workflows are unavailable.");
|
|
13089
|
+
return workflowBundleFromPreview(preview);
|
|
13090
|
+
}
|
|
13091
|
+
async importFlowBundle(file, options = {}) {
|
|
13092
|
+
return decodeWorkflowBundleImportResult(await this.request("/v1/flows/import-bundle", {
|
|
13093
|
+
method: "POST",
|
|
13094
|
+
headers: { "Idempotency-Key": options.idempotencyKey ?? `flow-${randomId()}` },
|
|
13095
|
+
body: JSON.stringify({
|
|
13096
|
+
file,
|
|
13097
|
+
name: options.name,
|
|
13098
|
+
teamId: options.teamId,
|
|
13099
|
+
tagIds: options.tagIds,
|
|
13100
|
+
version: 1
|
|
13101
|
+
})
|
|
13102
|
+
}));
|
|
13103
|
+
}
|
|
12802
13104
|
async importFlow(file, options = {}) {
|
|
12803
13105
|
return flow(await this.request("/v1/flows/import", {
|
|
12804
13106
|
method: "POST",
|
|
@@ -13455,4 +13757,4 @@ var ControlClient = class {
|
|
|
13455
13757
|
}
|
|
13456
13758
|
};
|
|
13457
13759
|
//#endregion
|
|
13458
|
-
export { ApiError, ControlClient, actionSummary, controlErrorCode, controlErrorMetadata, connectorAccess as decodeConnectorAccess, connectorAccessSnapshot as decodeConnectorAccessSnapshot, decodeEventSource, decodeEventSources, decodeResultList, decodeResultRead, decodeRunEvent, decodeTriggerCatalog, flowInputDefinitions, flowInspection, inspectFlowDraft, isRunTerminalEvent, liveEntries, nodeDetails, normalizeFlowQuery, parseProviderAccessSource, parseResultQuery, providerAccessBindingId, providerIconAppearance, readResult, searchTriggerKeys };
|
|
13760
|
+
export { ApiError, ControlClient, actionSummary, controlErrorCode, controlErrorMetadata, connectorAccess as decodeConnectorAccess, connectorAccessSnapshot as decodeConnectorAccessSnapshot, decodeEventSource, decodeEventSources, decodeResultList, decodeResultRead, decodeRunEvent, decodeTriggerCatalog, decodeWorkflowBundleImportResult, flowInputDefinitions, flowInspection, inspectFlowDraft, isRunTerminalEvent, liveEntries, nodeDetails, normalizeFlowQuery, parseProviderAccessSource, parseResultQuery, providerAccessBindingId, providerIconAppearance, readResult, searchTriggerKeys };
|
|
@@ -224,12 +224,10 @@ export declare const controlRequests: {
|
|
|
224
224
|
version: 1;
|
|
225
225
|
};
|
|
226
226
|
updateFlow: (value: unknown) => {
|
|
227
|
-
name: string;
|
|
228
|
-
tagIds?: string[] | undefined;
|
|
229
|
-
version: 1;
|
|
230
|
-
} | {
|
|
231
227
|
name?: string | undefined;
|
|
232
|
-
|
|
228
|
+
icon?: string | null | undefined;
|
|
229
|
+
description?: string | null | undefined;
|
|
230
|
+
tagIds?: string[] | undefined;
|
|
233
231
|
version: 1;
|
|
234
232
|
};
|
|
235
233
|
renameFlow: (value: unknown) => {
|
|
@@ -15393,6 +15393,21 @@ function applyFlowChanges(content, operations) {
|
|
|
15393
15393
|
});
|
|
15394
15394
|
}
|
|
15395
15395
|
//#endregion
|
|
15396
|
+
//#region src/connector/common/actionContract.ts
|
|
15397
|
+
/** These rules also apply to existing Revision snapshots without a catalog lookup. */
|
|
15398
|
+
var connectorActionContracts = { "leina.send_notification": {
|
|
15399
|
+
inputConstraints: [{
|
|
15400
|
+
handle: "leinaId",
|
|
15401
|
+
jsonSchema: {
|
|
15402
|
+
type: "string",
|
|
15403
|
+
pattern: "\\S"
|
|
15404
|
+
},
|
|
15405
|
+
code: "leina.robot-required",
|
|
15406
|
+
message: "Select a Leina robot or bind its identifier to an input source."
|
|
15407
|
+
}],
|
|
15408
|
+
pendingMessageInput: "message"
|
|
15409
|
+
} };
|
|
15410
|
+
//#endregion
|
|
15396
15411
|
//#region src/flow/common/edgeChanges.ts
|
|
15397
15412
|
function connect(content, edge) {
|
|
15398
15413
|
const selected = content.document.graph;
|
|
@@ -15403,11 +15418,12 @@ function connect(content, edge) {
|
|
|
15403
15418
|
}];
|
|
15404
15419
|
const source = selected.nodes[edge.source];
|
|
15405
15420
|
const target = selected.nodes[edge.target];
|
|
15406
|
-
|
|
15421
|
+
const messageInput = target?.kind == "task" && "executor" in target.task && target.task.executor.kind == "connector" ? connectorActionContracts[target.task.executor.action]?.pendingMessageInput : void 0;
|
|
15422
|
+
if (edge.sourceHandle == "pending" && (source?.kind == "approval" || source?.kind == "wait") && target?.kind == "task" && messageInput != null && (target.inputs[messageInput] == null || target.inputs[messageInput]?.kind == "unset")) changes.push({
|
|
15407
15423
|
kind: "graph.node.input.set",
|
|
15408
15424
|
nodeId: edge.target,
|
|
15409
|
-
handle:
|
|
15410
|
-
before: target.inputs
|
|
15425
|
+
handle: messageInput,
|
|
15426
|
+
before: target.inputs[messageInput],
|
|
15411
15427
|
value: {
|
|
15412
15428
|
kind: "sources",
|
|
15413
15429
|
sources: [{
|
|
@@ -17932,15 +17948,13 @@ var schemas = {
|
|
|
17932
17948
|
tagIds,
|
|
17933
17949
|
version
|
|
17934
17950
|
}),
|
|
17935
|
-
updateFlow:
|
|
17936
|
-
name: flowName,
|
|
17937
|
-
tagIds: tagIds.optional(),
|
|
17938
|
-
version
|
|
17939
|
-
}), strictObject({
|
|
17951
|
+
updateFlow: strictObject({
|
|
17940
17952
|
name: flowName.optional(),
|
|
17941
|
-
|
|
17953
|
+
icon: string().nullable().optional(),
|
|
17954
|
+
description: string().nullable().optional(),
|
|
17955
|
+
tagIds: tagIds.optional(),
|
|
17942
17956
|
version
|
|
17943
|
-
})
|
|
17957
|
+
}).refine((value) => value.name !== void 0 || value.icon !== void 0 || value.description !== void 0 || value.tagIds !== void 0, "Flow settings are empty."),
|
|
17944
17958
|
renameFlow: strictObject({
|
|
17945
17959
|
name: flowName,
|
|
17946
17960
|
version
|
|
@@ -57,6 +57,21 @@ function dequal(foo, bar) {
|
|
|
57
57
|
return foo !== foo && bar !== bar;
|
|
58
58
|
}
|
|
59
59
|
//#endregion
|
|
60
|
+
//#region src/connector/common/actionContract.ts
|
|
61
|
+
/** These rules also apply to existing Revision snapshots without a catalog lookup. */
|
|
62
|
+
var connectorActionContracts = { "leina.send_notification": {
|
|
63
|
+
inputConstraints: [{
|
|
64
|
+
handle: "leinaId",
|
|
65
|
+
jsonSchema: {
|
|
66
|
+
type: "string",
|
|
67
|
+
pattern: "\\S"
|
|
68
|
+
},
|
|
69
|
+
code: "leina.robot-required",
|
|
70
|
+
message: "Select a Leina robot or bind its identifier to an input source."
|
|
71
|
+
}],
|
|
72
|
+
pendingMessageInput: "message"
|
|
73
|
+
} };
|
|
74
|
+
//#endregion
|
|
60
75
|
//#region src/flow/common/edgeChanges.ts
|
|
61
76
|
function connect(content, edge) {
|
|
62
77
|
const selected = content.document.graph;
|
|
@@ -67,11 +82,12 @@ function connect(content, edge) {
|
|
|
67
82
|
}];
|
|
68
83
|
const source = selected.nodes[edge.source];
|
|
69
84
|
const target = selected.nodes[edge.target];
|
|
70
|
-
|
|
85
|
+
const messageInput = target?.kind == "task" && "executor" in target.task && target.task.executor.kind == "connector" ? connectorActionContracts[target.task.executor.action]?.pendingMessageInput : void 0;
|
|
86
|
+
if (edge.sourceHandle == "pending" && (source?.kind == "approval" || source?.kind == "wait") && target?.kind == "task" && messageInput != null && (target.inputs[messageInput] == null || target.inputs[messageInput]?.kind == "unset")) changes.push({
|
|
71
87
|
kind: "graph.node.input.set",
|
|
72
88
|
nodeId: edge.target,
|
|
73
|
-
handle:
|
|
74
|
-
before: target.inputs
|
|
89
|
+
handle: messageInput,
|
|
90
|
+
before: target.inputs[messageInput],
|
|
75
91
|
value: {
|
|
76
92
|
kind: "sources",
|
|
77
93
|
sources: [{
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CodeModule, FlowDocument, Graph, Group, InputMapping, InputPort, JsonValue, ManagedTaskDefinition, Port, RevisionContent, TriggerNode } from '@oomol-lab/open-flow/flow-change';
|
|
2
2
|
export * from './flow-workflowFile.js';
|
|
3
|
+
export * from './flow-workflowBundle.js';
|
|
3
4
|
export { maxJsonDepth } from './flow-json.js';
|
|
4
5
|
export { decodeFlowDocument, decodeRevisionContent, upgradeWorkflowInterfaceDocument } from './flow-change-schema.js';
|
|
5
6
|
export { upgradeRevisionContent } from '@oomol-lab/open-flow/flow-change';
|