@oomol-lab/open-flow 0.1.0-beta.51 → 0.1.0-beta.53
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/browser/{createResourceDialog-BDtXpRSt.js → createResourceDialog-BsaBMf7_.js} +2 -1
- package/dist/browser/flow-authoring.js +46 -3
- package/dist/browser/flow-change.d.ts +6 -1
- package/dist/browser/flow-change.js +46 -3
- package/dist/browser/{flowChanges-BWSXSnMX.js → flowChanges-CcscgZsW.js} +3492 -1939
- package/dist/browser/{flowWorkspace-DBaq2Eks.js → flowWorkspace-CoT_ewLX.js} +904 -330
- package/dist/browser/{workbenchSelect-C9kwcUmN.js → icons-0s-Q_3lp.js} +48 -32
- package/dist/browser/licenses.md +204 -0
- package/dist/browser/preview.css +282 -179
- package/dist/browser/preview.js +4311 -2200
- package/dist/browser/theme.css +2 -0
- package/dist/browser/ui-hostNavigationActions.d.ts +13 -0
- package/dist/browser/ui-hostTooltip.d.ts +8 -0
- package/dist/browser/ui-logo.d.ts +5 -0
- package/dist/browser/ui.css +82 -8
- package/dist/browser/ui.d.ts +3 -0
- package/dist/browser/ui.js +172 -8
- package/dist/browser/workbench-contract.d.ts +4 -11
- package/dist/browser/workbench.css +346 -200
- package/dist/browser/workbench.d.ts +1 -1
- package/dist/browser/workbench.js +1056 -367
- package/dist/browser/workbenchSelect-BqUPacsr.js +31 -0
- package/dist/common/authoringExamples.d.ts +4 -3
- package/dist/common/connector-proxy.d.ts +32 -0
- package/dist/common/control-api-conformance.js +54 -3
- package/dist/common/control-api.d.ts +6 -0
- package/dist/common/control-api.js +58 -4
- package/dist/common/control-requests.d.ts +4 -0
- package/dist/common/control-requests.js +1299 -68
- package/dist/common/feishu-subscriptions.d.ts +1 -5
- package/dist/common/flow-connectionUsage.d.ts +1 -0
- package/dist/common/flow-encoding.js +34 -0
- package/dist/common/flow-semantics.js +675 -252
- package/dist/common/integration-trigger.js +23 -0
- package/dist/common/mcp.js +54 -3
- package/dist/common/openapi.d.ts +53 -0
- package/dist/common/openapi.js +10390 -0
- package/dist/common/poll-trigger.js +23 -0
- package/dist/common/provider-triggers.d.ts +1 -1
- package/dist/common/provider-triggers.js +166 -16204
- package/dist/common/run-events.js +1 -0
- package/dist/common/scheduler.d.ts +1 -1
- package/dist/common/scheduler.js +31 -1
- package/dist/common/webhook-trigger.js +23 -0
- package/package.json +5 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { $t as
|
|
1
|
+
import { $t as InputGroup, At as flowDependencies, Bn as inputValue, Bt as followWorkbenchLink, Ct as resetInputValues, Dn as allConnectorConnectionsQuery, Dt as setTriggerConnection, En as randomId, Et as setInputSources, F as deriveAddNodeOptions, G as resourceValue, Gn as providerIconAppearance, H as CacheResource, Hn as jsonValue, Ht as Popover, K as designerGraph, Kn as ApiError, Kt as PopoverTitle, L as feishuResourceKind, Mn as sampleErrorOutputs, Nn as triggerOutputDefinitions, Ot as updateTriggerConfig, P as addNodeIntent, Pn as isJsonObject, R as supportsFeishuChatFilter, Rn as connection, St as repairNodeNames, Tn as WorkbenchClient, Tt as setConnectorConnection, Un as record, Ut as PopoverContent, V as scopedValue, Vn as invalidResponse, Vt as Switch, W as resourceData, Wn as string, X as providerIcon, Yn as IconThemeContext, _ as updateTaskAdditionalInputs, _t as setComment, a as deleteSelection, an as EmptyHeader, at as Latest, b as updateWebhook, bt as setNodePositions, c as setInputVariable, cn as EventSourcesPage, d as updateNodeIcon, dn as createI18n, dt as actionWithConnections, en as InputGroupAddon, f as updateNodeName, ft as connectionCatalog, g as updateTask, gt as restoreCanvasPresentation, h as updateSubflow, ht as removeComments, i as createResource, in as EmptyDescription, it as revisionView, kn as decodeTriggerCatalog, kt as updateTriggerSchedule, l as updateCondition, m as updateResolution, mt as commentIds, nn as Empty, o as nameCreatedNodes, on as EmptyMedia, ot as deriveInspectorDiagnostics, p as updateNodeSettings, pt as canvasPresentationChange, qn as controlErrorCode, qt as PopoverTrigger, r as applyFlowChanges, rn as EmptyContent, s as setInputValue, sn as EmptyTitle, st as diagnosticItems, t as addNode, tn as InputGroupInput, tt as RunStore, u as updateNodeDescription, v as updateTaskPorts, vt as setFlowViewport, wn as errorNotice, wt as setCodeActions, xt as targetPresentation, y as updateValue, yt as setNodeContentHidden, z as combineSources, zn as connectorActionMetadata, zt as IdTooltip } from "./flowChanges-CcscgZsW.js";
|
|
2
2
|
import { a as derive, i as compute, l as val } from "./dist-bO8nvHFH.js";
|
|
3
3
|
import { a as useVal, i as useTranslate, r as useLang, t as I18nProvider } from "./main-BPABKzwN.js";
|
|
4
|
-
import {
|
|
4
|
+
import { C as FieldError, D as applyFlowChanges$1, E as FlowChangeError, I as mapConditionSources, Ir as cn, K as dequal$1, L as nodeInputMappings, N as resourceNameIssue, Pr as Button, T as FieldLabel, a as DialogDescription, b as Spinner, c as DialogTitle, d as TooltipContent, i as DialogContent, jn as Input, n as Dialog, o as DialogFooter, p as TooltipTrigger, r as DialogClose, s as DialogHeader, t as Icon, u as Tooltip, w as FieldGroup, x as Field } from "./icons-0s-Q_3lp.js";
|
|
5
5
|
import { a as toPlainObject } from "./dist-BDBTOgS5.js";
|
|
6
6
|
import { c as isUiLanguage, d as uiLanguages, l as resolveUiLanguage, u as uiLanguageNames } from "./value-DL_poNiC.js";
|
|
7
7
|
import { Suspense, lazy, useEffect, useRef, useState } from "react";
|
|
@@ -196,34 +196,11 @@ function Skeleton({ className, ...props }) {
|
|
|
196
196
|
}
|
|
197
197
|
//#endregion
|
|
198
198
|
//#region src/workbench/browser/runtime/shell/resourceBrowser.tsx
|
|
199
|
-
var CreateResourceDialog = lazy(() => import("./createResourceDialog-
|
|
200
|
-
var languageOptions = uiLanguages.map((language) => ({
|
|
201
|
-
label: uiLanguageNames[language],
|
|
202
|
-
value: language
|
|
203
|
-
}));
|
|
199
|
+
var CreateResourceDialog = lazy(() => import("./createResourceDialog-BsaBMf7_.js"));
|
|
204
200
|
var flowIdTooltipAlignOffset = 44;
|
|
205
201
|
var renamePopoverAlignOffset = -12;
|
|
206
202
|
var renamePopoverVerticalShift = 8;
|
|
207
203
|
var rowControlSelector = "a, button, input, select, textarea, [data-slot=\"tooltip-trigger\"]";
|
|
208
|
-
function LanguageSelect({ language, onLanguageChange }) {
|
|
209
|
-
const t = useTranslate();
|
|
210
|
-
const [portalRoot, setPortalRoot] = useState(null);
|
|
211
|
-
if (onLanguageChange == null) return null;
|
|
212
|
-
return /* @__PURE__ */ jsxs("div", {
|
|
213
|
-
className: "resource-language",
|
|
214
|
-
ref: setPortalRoot,
|
|
215
|
-
children: [/* @__PURE__ */ jsx("span", {
|
|
216
|
-
className: "sr-only",
|
|
217
|
-
children: t("language.label")
|
|
218
|
-
}), /* @__PURE__ */ jsx(WorkbenchSelect, {
|
|
219
|
-
ariaLabel: t("language.label"),
|
|
220
|
-
onValueChange: (value) => onLanguageChange(value),
|
|
221
|
-
options: languageOptions,
|
|
222
|
-
portalRoot,
|
|
223
|
-
value: language
|
|
224
|
-
})]
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
204
|
function compactFlowId(flowId) {
|
|
228
205
|
return flowId.length <= 20 ? flowId : `${flowId.slice(0, 10)}…${flowId.slice(-6)}`;
|
|
229
206
|
}
|
|
@@ -504,12 +481,19 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
|
|
|
504
481
|
"aria-hidden": "true",
|
|
505
482
|
className: cn("status-dot", publicationTone)
|
|
506
483
|
}),
|
|
507
|
-
t(publicationStatus),
|
|
508
|
-
flow.live != null && /* @__PURE__ */ jsxs(
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
children: "
|
|
512
|
-
|
|
484
|
+
/* @__PURE__ */ jsx("span", { children: t(publicationStatus) }),
|
|
485
|
+
flow.live != null && /* @__PURE__ */ jsxs("span", {
|
|
486
|
+
className: "resource-enabled-status",
|
|
487
|
+
"aria-busy": pending == "enabled",
|
|
488
|
+
children: [/* @__PURE__ */ jsx("span", { children: t(flow.live.enabled ? "resource.enabled" : "resource.disabled") }), /* @__PURE__ */ jsx(Switch, {
|
|
489
|
+
"aria-label": t("resource.enableFlow", { name: flow.name }),
|
|
490
|
+
checked: flow.live.enabled,
|
|
491
|
+
disabled: flow.status != "active" || busy != null || pending != null,
|
|
492
|
+
onCheckedChange: (enabled) => void update(enabled),
|
|
493
|
+
size: "sm",
|
|
494
|
+
title: t("resource.enabledHint")
|
|
495
|
+
})]
|
|
496
|
+
})
|
|
513
497
|
]
|
|
514
498
|
})
|
|
515
499
|
]
|
|
@@ -519,14 +503,6 @@ function FlowItem({ badge, busy, flow, href, onSelect, store }) {
|
|
|
519
503
|
"aria-busy": pending != null,
|
|
520
504
|
onClick: openFromRow,
|
|
521
505
|
children: [
|
|
522
|
-
flow.live != null && /* @__PURE__ */ jsx(Switch, {
|
|
523
|
-
"aria-label": t("resource.enableFlow", { name: flow.name }),
|
|
524
|
-
checked: flow.live.enabled,
|
|
525
|
-
disabled: flow.status != "active" || busy != null || pending != null,
|
|
526
|
-
onCheckedChange: (enabled) => void update(enabled),
|
|
527
|
-
size: "sm",
|
|
528
|
-
title: t("resource.enabledHint")
|
|
529
|
-
}),
|
|
530
506
|
flow.status == "active" && /* @__PURE__ */ jsx(Button, {
|
|
531
507
|
onClick: () => onSelect(flow),
|
|
532
508
|
size: "sm",
|
|
@@ -619,7 +595,7 @@ function FlowSkeleton() {
|
|
|
619
595
|
})]
|
|
620
596
|
});
|
|
621
597
|
}
|
|
622
|
-
function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBadges, hrefForFlow,
|
|
598
|
+
function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBadges, hrefForFlow, onCreateFlow, onSelectFlow, store }) {
|
|
623
599
|
const t = useTranslate();
|
|
624
600
|
const busy = useVal(store.workspace.$.busy);
|
|
625
601
|
const loadFailed = useVal(store.workspace.$.flowLoadFailed);
|
|
@@ -666,107 +642,105 @@ function FlowBrowser({ catalogWidth, createFlowDisabled, createFlowField, flowBa
|
|
|
666
642
|
}), !loading && /* @__PURE__ */ jsx("span", { children: t("resource.flowCount", { count: total ?? flows.length }) })]
|
|
667
643
|
}), /* @__PURE__ */ jsxs("div", {
|
|
668
644
|
className: "resource-list-actions",
|
|
669
|
-
children: [
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
/* @__PURE__ */
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
value: filter
|
|
686
|
-
})]
|
|
687
|
-
}),
|
|
688
|
-
/* @__PURE__ */ jsxs(Button, {
|
|
689
|
-
className: "pr-3",
|
|
690
|
-
disabled: busy != null,
|
|
691
|
-
onClick: () => setCreating(true),
|
|
692
|
-
children: [/* @__PURE__ */ jsx(Icon, {
|
|
693
|
-
"data-icon": "inline-start",
|
|
694
|
-
name: "plus"
|
|
695
|
-
}), t("resource.newFlow")]
|
|
696
|
-
})
|
|
697
|
-
]
|
|
698
|
-
})]
|
|
699
|
-
}),
|
|
700
|
-
/* @__PURE__ */ jsxs("div", {
|
|
701
|
-
"aria-hidden": "true",
|
|
702
|
-
className: "resource-list-columns-shell",
|
|
703
|
-
children: [/* @__PURE__ */ jsxs("div", {
|
|
704
|
-
className: "resource-list-columns flow-columns",
|
|
705
|
-
children: [
|
|
706
|
-
/* @__PURE__ */ jsx("span", { children: t("resource.name") }),
|
|
707
|
-
/* @__PURE__ */ jsx("span", {
|
|
708
|
-
className: "resource-flow-id-heading",
|
|
709
|
-
children: t("resource.flowId")
|
|
710
|
-
}),
|
|
711
|
-
/* @__PURE__ */ jsx("span", {
|
|
712
|
-
className: "resource-updated-heading",
|
|
713
|
-
children: t("resource.updated")
|
|
714
|
-
}),
|
|
715
|
-
/* @__PURE__ */ jsx("span", { children: t("resource.status") })
|
|
716
|
-
]
|
|
717
|
-
}), /* @__PURE__ */ jsx("span", {
|
|
718
|
-
className: "resource-actions-heading",
|
|
719
|
-
children: t("resource.actions")
|
|
720
|
-
})]
|
|
721
|
-
}),
|
|
722
|
-
/* @__PURE__ */ jsx("div", {
|
|
723
|
-
className: "resource-list",
|
|
724
|
-
children: loading ? Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx(FlowSkeleton, {}, index)) : loadFailed ? /* @__PURE__ */ jsxs(Empty, {
|
|
725
|
-
className: "min-h-64",
|
|
726
|
-
role: "alert",
|
|
727
|
-
children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
|
|
728
|
-
/* @__PURE__ */ jsx(EmptyMedia, {
|
|
729
|
-
variant: "icon",
|
|
730
|
-
children: /* @__PURE__ */ jsx(Icon, {
|
|
731
|
-
name: "alert",
|
|
732
|
-
size: 20
|
|
733
|
-
})
|
|
734
|
-
}),
|
|
735
|
-
/* @__PURE__ */ jsx(EmptyTitle, { children: t("resource.flowsLoadFailed") }),
|
|
736
|
-
/* @__PURE__ */ jsx(EmptyDescription, { children: t("resource.flowsLoadFailedDescription") })
|
|
737
|
-
] }), /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsx(Button, {
|
|
738
|
-
onClick: () => void store.retryFlows(),
|
|
739
|
-
variant: "outline",
|
|
740
|
-
children: t("empty.retry")
|
|
741
|
-
}) })]
|
|
742
|
-
}) : visible.length == 0 ? /* @__PURE__ */ jsxs(Empty, {
|
|
743
|
-
className: "min-h-64",
|
|
744
|
-
children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
|
|
745
|
-
/* @__PURE__ */ jsx(EmptyMedia, {
|
|
746
|
-
variant: "icon",
|
|
747
|
-
children: /* @__PURE__ */ jsx(Icon, {
|
|
748
|
-
name: "flow",
|
|
749
|
-
size: 20
|
|
750
|
-
})
|
|
751
|
-
}),
|
|
752
|
-
/* @__PURE__ */ jsx(EmptyTitle, { children: t(normalized.length == 0 ? "resource.noFlows" : "resource.noMatchingFlows") }),
|
|
753
|
-
/* @__PURE__ */ jsx(EmptyDescription, { children: t(normalized.length == 0 ? "resource.noFlowsDescription" : "resource.noMatchingDescription") })
|
|
754
|
-
] }), normalized.length == 0 && /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsxs(Button, {
|
|
645
|
+
children: [/* @__PURE__ */ jsxs(InputGroup, {
|
|
646
|
+
className: "w-full sm:w-56",
|
|
647
|
+
children: [/* @__PURE__ */ jsx(InputGroupAddon, { children: /* @__PURE__ */ jsx(Icon, {
|
|
648
|
+
name: "search",
|
|
649
|
+
size: 17
|
|
650
|
+
}) }), /* @__PURE__ */ jsx(InputGroupInput, {
|
|
651
|
+
autoComplete: "off",
|
|
652
|
+
"aria-label": t("resource.searchByName"),
|
|
653
|
+
name: "flow-search",
|
|
654
|
+
onChange: (event) => setFilter(event.target.value),
|
|
655
|
+
placeholder: t("resource.searchByName"),
|
|
656
|
+
value: filter
|
|
657
|
+
})]
|
|
658
|
+
}), /* @__PURE__ */ jsxs(Button, {
|
|
659
|
+
className: "pr-3",
|
|
660
|
+
disabled: busy != null,
|
|
755
661
|
onClick: () => setCreating(true),
|
|
756
|
-
variant: "outline",
|
|
757
662
|
children: [/* @__PURE__ */ jsx(Icon, {
|
|
758
663
|
"data-icon": "inline-start",
|
|
759
664
|
name: "plus"
|
|
760
665
|
}), t("resource.newFlow")]
|
|
761
|
-
})
|
|
762
|
-
})
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
666
|
+
})]
|
|
667
|
+
})]
|
|
668
|
+
}),
|
|
669
|
+
/* @__PURE__ */ jsx("div", {
|
|
670
|
+
className: "resource-table-scroll",
|
|
671
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
672
|
+
className: "resource-table",
|
|
673
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
674
|
+
"aria-hidden": "true",
|
|
675
|
+
className: "resource-list-columns-shell",
|
|
676
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
677
|
+
className: "resource-list-columns flow-columns",
|
|
678
|
+
children: [
|
|
679
|
+
/* @__PURE__ */ jsx("span", { children: t("resource.name") }),
|
|
680
|
+
/* @__PURE__ */ jsx("span", {
|
|
681
|
+
className: "resource-flow-id-heading",
|
|
682
|
+
children: t("resource.flowId")
|
|
683
|
+
}),
|
|
684
|
+
/* @__PURE__ */ jsx("span", {
|
|
685
|
+
className: "resource-updated-heading",
|
|
686
|
+
children: t("resource.updated")
|
|
687
|
+
}),
|
|
688
|
+
/* @__PURE__ */ jsx("span", { children: t("resource.status") })
|
|
689
|
+
]
|
|
690
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
691
|
+
className: "resource-actions-heading",
|
|
692
|
+
children: t("resource.actions")
|
|
693
|
+
})]
|
|
694
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
695
|
+
className: "resource-list",
|
|
696
|
+
children: loading ? Array.from({ length: 5 }, (_, index) => /* @__PURE__ */ jsx(FlowSkeleton, {}, index)) : loadFailed ? /* @__PURE__ */ jsxs(Empty, {
|
|
697
|
+
className: "min-h-64",
|
|
698
|
+
role: "alert",
|
|
699
|
+
children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
|
|
700
|
+
/* @__PURE__ */ jsx(EmptyMedia, {
|
|
701
|
+
variant: "icon",
|
|
702
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
703
|
+
name: "alert",
|
|
704
|
+
size: 20
|
|
705
|
+
})
|
|
706
|
+
}),
|
|
707
|
+
/* @__PURE__ */ jsx(EmptyTitle, { children: t("resource.flowsLoadFailed") }),
|
|
708
|
+
/* @__PURE__ */ jsx(EmptyDescription, { children: t("resource.flowsLoadFailedDescription") })
|
|
709
|
+
] }), /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsx(Button, {
|
|
710
|
+
onClick: () => void store.retryFlows(),
|
|
711
|
+
variant: "outline",
|
|
712
|
+
children: t("empty.retry")
|
|
713
|
+
}) })]
|
|
714
|
+
}) : visible.length == 0 ? /* @__PURE__ */ jsxs(Empty, {
|
|
715
|
+
className: "min-h-64",
|
|
716
|
+
children: [/* @__PURE__ */ jsxs(EmptyHeader, { children: [
|
|
717
|
+
/* @__PURE__ */ jsx(EmptyMedia, {
|
|
718
|
+
variant: "icon",
|
|
719
|
+
children: /* @__PURE__ */ jsx(Icon, {
|
|
720
|
+
name: "flow",
|
|
721
|
+
size: 20
|
|
722
|
+
})
|
|
723
|
+
}),
|
|
724
|
+
/* @__PURE__ */ jsx(EmptyTitle, { children: t(normalized.length == 0 ? "resource.noFlows" : "resource.noMatchingFlows") }),
|
|
725
|
+
/* @__PURE__ */ jsx(EmptyDescription, { children: t(normalized.length == 0 ? "resource.noFlowsDescription" : "resource.noMatchingDescription") })
|
|
726
|
+
] }), normalized.length == 0 && /* @__PURE__ */ jsx(EmptyContent, { children: /* @__PURE__ */ jsxs(Button, {
|
|
727
|
+
onClick: () => setCreating(true),
|
|
728
|
+
variant: "outline",
|
|
729
|
+
children: [/* @__PURE__ */ jsx(Icon, {
|
|
730
|
+
"data-icon": "inline-start",
|
|
731
|
+
name: "plus"
|
|
732
|
+
}), t("resource.newFlow")]
|
|
733
|
+
}) })]
|
|
734
|
+
}) : visible.map((flow) => /* @__PURE__ */ jsx(FlowItem, {
|
|
735
|
+
badge: flowBadges?.[flow.flowId],
|
|
736
|
+
busy,
|
|
737
|
+
flow,
|
|
738
|
+
href: hrefForFlow(flow),
|
|
739
|
+
onSelect: onSelectFlow,
|
|
740
|
+
store
|
|
741
|
+
}, flow.flowId))
|
|
742
|
+
})]
|
|
743
|
+
})
|
|
770
744
|
}),
|
|
771
745
|
nextCursor != null && /* @__PURE__ */ jsx("div", {
|
|
772
746
|
className: "resource-list-footer",
|
|
@@ -1506,93 +1480,35 @@ var PublicationStore = class {
|
|
|
1506
1480
|
//#endregion
|
|
1507
1481
|
//#region src/workbench/browser/runtime/runs/runRequestStore.ts
|
|
1508
1482
|
var initialState$5 = { starting: false };
|
|
1509
|
-
function
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
}
|
|
1518
|
-
}
|
|
1519
|
-
function nodeTitle(node) {
|
|
1520
|
-
if (node.node.name != null) return node.node.name;
|
|
1521
|
-
if (node.kind == "task" || node.kind == "subflow") return node.definition?.name ?? node.id;
|
|
1522
|
-
return node.id;
|
|
1523
|
-
}
|
|
1524
|
-
function inputSpecs(draft, triggerId) {
|
|
1525
|
-
const revision = revisionView(draft);
|
|
1526
|
-
const graph = revision.graph({ kind: "flow" });
|
|
1527
|
-
if (graph == null) return [];
|
|
1528
|
-
const reachable = /* @__PURE__ */ new Set([triggerId]);
|
|
1529
|
-
const pending = [triggerId];
|
|
1530
|
-
while (pending.length > 0) {
|
|
1531
|
-
const source = pending.pop();
|
|
1532
|
-
for (const edge of graph.edges) {
|
|
1533
|
-
if (edge.source != source || reachable.has(edge.target)) continue;
|
|
1534
|
-
reachable.add(edge.target);
|
|
1535
|
-
pending.push(edge.target);
|
|
1536
|
-
}
|
|
1537
|
-
}
|
|
1538
|
-
return Object.entries(graph.nodes).filter(([id]) => reachable.has(id)).toSorted(([left], [right]) => left.localeCompare(right)).flatMap(([nodeId, node]) => {
|
|
1539
|
-
const resolved = revision.resolveNode(nodeId, node);
|
|
1540
|
-
if (resolved.kind == "trigger") {
|
|
1541
|
-
if (resolved.trigger.kind == "manual" || resolved.trigger.kind == "cron") return [];
|
|
1542
|
-
return [{
|
|
1543
|
-
definitions: triggerOutputDefinitions(resolved.trigger),
|
|
1544
|
-
samples: resolved.trigger.kind == "error" ? sampleErrorOutputs : void 0,
|
|
1545
|
-
nodeId,
|
|
1546
|
-
title: resolved.trigger.name
|
|
1547
|
-
}];
|
|
1548
|
-
}
|
|
1549
|
-
const definitions = Object.entries(inputPorts$1(resolved)).filter(([handle, port]) => resolved.node.inputs[handle] == null && !Object.hasOwn(port, "value")).toSorted(([left], [right]) => left.localeCompare(right)).map(([handle, port]) => Object.assign({
|
|
1550
|
-
handle,
|
|
1551
|
-
jsonSchema: port.jsonSchema,
|
|
1552
|
-
nullable: port.nullable
|
|
1553
|
-
}, port.description == null ? {} : { description: port.description }));
|
|
1554
|
-
return definitions.length == 0 ? [] : [{
|
|
1555
|
-
definitions,
|
|
1556
|
-
samples: void 0,
|
|
1557
|
-
nodeId,
|
|
1558
|
-
title: nodeTitle(resolved)
|
|
1559
|
-
}];
|
|
1560
|
-
});
|
|
1483
|
+
function inputSpec(draft, triggerId) {
|
|
1484
|
+
const trigger = revisionView(draft).graph({ kind: "flow" })?.nodes[triggerId];
|
|
1485
|
+
if (trigger == null || "inputs" in trigger || trigger.kind == "manual" || trigger.kind == "cron") return void 0;
|
|
1486
|
+
const definitions = triggerOutputDefinitions(trigger);
|
|
1487
|
+
return definitions.length === 0 ? void 0 : {
|
|
1488
|
+
definitions,
|
|
1489
|
+
samples: trigger.kind == "error" ? sampleErrorOutputs : void 0
|
|
1490
|
+
};
|
|
1561
1491
|
}
|
|
1562
|
-
function inputSignature(
|
|
1563
|
-
return JSON.stringify(
|
|
1492
|
+
function inputSignature(spec) {
|
|
1493
|
+
return JSON.stringify(spec?.definitions.map((definition) => [
|
|
1564
1494
|
definition.handle,
|
|
1565
1495
|
definition.jsonSchema,
|
|
1566
1496
|
definition.nullable
|
|
1567
|
-
])])
|
|
1497
|
+
]) ?? []);
|
|
1568
1498
|
}
|
|
1569
|
-
async function
|
|
1499
|
+
async function inputEditor(spec, language, values) {
|
|
1500
|
+
if (spec == null) return void 0;
|
|
1570
1501
|
const { FlowRunInputEditorStore } = await import("./flowRunInputEditorStore-Dsxyfwae.js").then((n) => n.t);
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
return {
|
|
1576
|
-
editor,
|
|
1577
|
-
nodeId: group.nodeId,
|
|
1578
|
-
title: group.title
|
|
1579
|
-
};
|
|
1580
|
-
});
|
|
1581
|
-
}
|
|
1582
|
-
function groupValues(groups) {
|
|
1583
|
-
return Object.fromEntries(groups.map((group) => [group.nodeId, group.editor.values()]));
|
|
1502
|
+
const editor = new FlowRunInputEditorStore(spec.definitions, language);
|
|
1503
|
+
const initial = values ?? spec.samples;
|
|
1504
|
+
if (initial != null) editor.replaceValues(initial);
|
|
1505
|
+
return editor;
|
|
1584
1506
|
}
|
|
1585
1507
|
function testOutputs(revision, triggerId) {
|
|
1586
1508
|
const node = revisionView(revision).graph({ kind: "flow" })?.nodes[triggerId];
|
|
1587
1509
|
if (node?.kind == "error") return sampleErrorOutputs;
|
|
1588
1510
|
return node?.kind === "cron" ? { scheduledAt: (/* @__PURE__ */ new Date()).toISOString() } : {};
|
|
1589
1511
|
}
|
|
1590
|
-
function runValues(groups, triggerId, revision) {
|
|
1591
|
-
return {
|
|
1592
|
-
inputs: Object.fromEntries(groups.filter((group) => group.nodeId != triggerId).map((group) => [group.nodeId, group.editor.values()])),
|
|
1593
|
-
outputs: groups.find((group) => group.nodeId == triggerId)?.editor.values() ?? testOutputs(revision, triggerId)
|
|
1594
|
-
};
|
|
1595
|
-
}
|
|
1596
1512
|
var RunRequestStore = class {
|
|
1597
1513
|
#prepareDraft;
|
|
1598
1514
|
#client;
|
|
@@ -1657,10 +1573,10 @@ var RunRequestStore = class {
|
|
|
1657
1573
|
}
|
|
1658
1574
|
}
|
|
1659
1575
|
inputStatus(flowId, draft, triggerId) {
|
|
1660
|
-
const
|
|
1661
|
-
if (
|
|
1576
|
+
const spec = inputSpec(draft, triggerId);
|
|
1577
|
+
if (spec == null) return "none";
|
|
1662
1578
|
const saved = this.#savedInputs.get(this.#inputKey(flowId, triggerId));
|
|
1663
|
-
return saved?.valid == true && saved.signature == inputSignature(
|
|
1579
|
+
return saved?.valid == true && saved.signature == inputSignature(spec) ? "ready" : "missing";
|
|
1664
1580
|
}
|
|
1665
1581
|
async requestLive(flow) {
|
|
1666
1582
|
const current = this.#requests.begin();
|
|
@@ -1695,11 +1611,11 @@ var RunRequestStore = class {
|
|
|
1695
1611
|
return false;
|
|
1696
1612
|
}
|
|
1697
1613
|
this.#rememberInputs(request);
|
|
1698
|
-
const
|
|
1614
|
+
const outputs = request.editor?.values() ?? testOutputs(request.revision, request.triggerId);
|
|
1699
1615
|
const started = await this.#start(request.source, request.flow, request.revisionId, {
|
|
1700
1616
|
nodeId: request.triggerId,
|
|
1701
1617
|
outputs
|
|
1702
|
-
},
|
|
1618
|
+
}, request.publicationId);
|
|
1703
1619
|
if (started && this.#state.value.inputRequest === request) this.dismissInputs();
|
|
1704
1620
|
return started;
|
|
1705
1621
|
}
|
|
@@ -1710,18 +1626,18 @@ var RunRequestStore = class {
|
|
|
1710
1626
|
this.#rememberInputs(request);
|
|
1711
1627
|
this.#set({ starting: true });
|
|
1712
1628
|
try {
|
|
1713
|
-
const
|
|
1629
|
+
const spec = inputSpec(request.revision, triggerId);
|
|
1714
1630
|
const saved = this.#savedInputs.get(this.#inputKey(request.flow.flowId, triggerId));
|
|
1715
|
-
const
|
|
1631
|
+
const editor = await inputEditor(spec, this.#i18n.lang$, saved?.values);
|
|
1716
1632
|
if (!current() || this.#state.value.inputRequest !== request) {
|
|
1717
|
-
|
|
1633
|
+
editor?.dispose();
|
|
1718
1634
|
return;
|
|
1719
1635
|
}
|
|
1720
|
-
const valid = compute((get) =>
|
|
1636
|
+
const valid = compute((get) => editor == null || get(editor.valid$));
|
|
1721
1637
|
this.#set({ inputRequest: {
|
|
1722
1638
|
...request,
|
|
1723
1639
|
attempted: false,
|
|
1724
|
-
|
|
1640
|
+
editor,
|
|
1725
1641
|
triggerId,
|
|
1726
1642
|
valid
|
|
1727
1643
|
} });
|
|
@@ -1763,32 +1679,32 @@ var RunRequestStore = class {
|
|
|
1763
1679
|
});
|
|
1764
1680
|
return "unavailable";
|
|
1765
1681
|
}
|
|
1766
|
-
const
|
|
1767
|
-
const signature = inputSignature(
|
|
1682
|
+
const spec = only == null ? void 0 : inputSpec(revision, only.nodeId);
|
|
1683
|
+
const signature = inputSignature(spec);
|
|
1768
1684
|
const saved = only == null ? void 0 : this.#savedInputs.get(this.#inputKey(flow.flowId, only.nodeId));
|
|
1769
|
-
const
|
|
1685
|
+
const editor = await inputEditor(spec, this.#i18n.lang$, saved?.values);
|
|
1770
1686
|
if (!current()) {
|
|
1771
|
-
|
|
1687
|
+
editor?.dispose();
|
|
1772
1688
|
return "unavailable";
|
|
1773
1689
|
}
|
|
1774
|
-
if (!edit && only != null &&
|
|
1690
|
+
if (!edit && only != null && editor == null) return await this.#start(source, flow, revisionId, {
|
|
1775
1691
|
nodeId: only.nodeId,
|
|
1776
1692
|
outputs: testOutputs(revision, only.nodeId)
|
|
1777
|
-
},
|
|
1778
|
-
if (!edit && only != null && saved?.valid == true && saved.signature == signature &&
|
|
1779
|
-
const
|
|
1780
|
-
|
|
1693
|
+
}, publicationId) ? "started" : "unavailable";
|
|
1694
|
+
if (!edit && only != null && saved?.valid == true && saved.signature == signature && editor != null && editor.valid$.value) {
|
|
1695
|
+
const outputs = editor.values();
|
|
1696
|
+
editor?.dispose();
|
|
1781
1697
|
return await this.#start(source, flow, revisionId, {
|
|
1782
1698
|
nodeId: only.nodeId,
|
|
1783
|
-
outputs
|
|
1784
|
-
},
|
|
1699
|
+
outputs
|
|
1700
|
+
}, publicationId) ? "started" : "unavailable";
|
|
1785
1701
|
}
|
|
1786
|
-
const valid = compute((get) => only != null &&
|
|
1702
|
+
const valid = compute((get) => only != null && (editor == null || get(editor.valid$)));
|
|
1787
1703
|
this.#set({
|
|
1788
1704
|
inputRequest: {
|
|
1789
1705
|
attempted: false,
|
|
1790
1706
|
flow,
|
|
1791
|
-
|
|
1707
|
+
editor,
|
|
1792
1708
|
revision,
|
|
1793
1709
|
triggers,
|
|
1794
1710
|
triggerId: only?.nodeId,
|
|
@@ -1802,7 +1718,7 @@ var RunRequestStore = class {
|
|
|
1802
1718
|
});
|
|
1803
1719
|
return "input";
|
|
1804
1720
|
}
|
|
1805
|
-
async #start(source, flow, revisionId, trigger,
|
|
1721
|
+
async #start(source, flow, revisionId, trigger, publicationId) {
|
|
1806
1722
|
if (source == "live" && publicationId == null) return false;
|
|
1807
1723
|
const alive = this.#lifetime.capture();
|
|
1808
1724
|
const current = this.#runs.prepareStart();
|
|
@@ -1821,7 +1737,6 @@ var RunRequestStore = class {
|
|
|
1821
1737
|
revisionId
|
|
1822
1738
|
} : { publicationId };
|
|
1823
1739
|
const signature = JSON.stringify({
|
|
1824
|
-
inputs,
|
|
1825
1740
|
trigger,
|
|
1826
1741
|
source,
|
|
1827
1742
|
...target
|
|
@@ -1833,11 +1748,11 @@ var RunRequestStore = class {
|
|
|
1833
1748
|
this.#attempt = attempt;
|
|
1834
1749
|
const run = source == "draft" ? await this.#client.createDraftRun(flow.flowId, revisionId, {
|
|
1835
1750
|
idempotencyKey: attempt.key,
|
|
1836
|
-
inputs,
|
|
1751
|
+
inputs: {},
|
|
1837
1752
|
trigger
|
|
1838
1753
|
}) : await this.#client.createLiveRun(publicationId, {
|
|
1839
1754
|
idempotencyKey: attempt.key,
|
|
1840
|
-
inputs,
|
|
1755
|
+
inputs: {},
|
|
1841
1756
|
trigger
|
|
1842
1757
|
});
|
|
1843
1758
|
if (!alive() || !current()) return false;
|
|
@@ -1856,17 +1771,17 @@ var RunRequestStore = class {
|
|
|
1856
1771
|
#disposeInputRequest(request = this.#state.value.inputRequest) {
|
|
1857
1772
|
if (request == null) return;
|
|
1858
1773
|
request.valid.dispose();
|
|
1859
|
-
|
|
1774
|
+
request.editor?.dispose();
|
|
1860
1775
|
}
|
|
1861
1776
|
#inputKey(flowId, triggerId) {
|
|
1862
1777
|
return `${flowId}\u0000${triggerId}`;
|
|
1863
1778
|
}
|
|
1864
1779
|
#rememberInputs(request) {
|
|
1865
|
-
if (request?.triggerId == null || request.
|
|
1780
|
+
if (request?.triggerId == null || request.editor == null) return;
|
|
1866
1781
|
this.#savedInputs.set(this.#inputKey(request.flow.flowId, request.triggerId), {
|
|
1867
|
-
signature: inputSignature(
|
|
1782
|
+
signature: inputSignature(inputSpec(request.revision, request.triggerId)),
|
|
1868
1783
|
valid: request.valid.value,
|
|
1869
|
-
values:
|
|
1784
|
+
values: request.editor.values()
|
|
1870
1785
|
});
|
|
1871
1786
|
}
|
|
1872
1787
|
#set(patch) {
|
|
@@ -1961,48 +1876,591 @@ function createStore(dbName, storeName) {
|
|
|
1961
1876
|
};
|
|
1962
1877
|
return (txMode, callback) => getDB().then((db) => callback(db.transaction(storeName, txMode).objectStore(storeName)));
|
|
1963
1878
|
}
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
return
|
|
1968
|
-
}
|
|
1969
|
-
/**
|
|
1970
|
-
* Get a value by its key.
|
|
1971
|
-
*
|
|
1972
|
-
* @param key
|
|
1973
|
-
* @param customStore Method to get a custom store. Use with caution (see the docs).
|
|
1974
|
-
*/
|
|
1975
|
-
function get(key, customStore = defaultGetStore()) {
|
|
1976
|
-
return customStore("readonly", (store) => promisifyRequest(store.get(key)));
|
|
1879
|
+
//#endregion
|
|
1880
|
+
//#region ../../node_modules/.bun/@oomol-lab+resource-cache@0.1.4/node_modules/@oomol-lab/resource-cache/dist/src-bwD0r9NQ.mjs
|
|
1881
|
+
function abortError() {
|
|
1882
|
+
return new DOMException("Cache operation aborted", "AbortError");
|
|
1977
1883
|
}
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1884
|
+
function wait(promise, lifetime, caller) {
|
|
1885
|
+
const signals = caller ? [lifetime, caller] : [lifetime];
|
|
1886
|
+
return new Promise((resolve, reject) => {
|
|
1887
|
+
const cleanup = () => {
|
|
1888
|
+
for (const signal of signals) signal.removeEventListener("abort", abort);
|
|
1889
|
+
};
|
|
1890
|
+
const abort = () => {
|
|
1891
|
+
cleanup();
|
|
1892
|
+
reject(abortError());
|
|
1893
|
+
};
|
|
1894
|
+
for (const signal of signals) signal.addEventListener("abort", abort, { once: true });
|
|
1895
|
+
promise.then((value) => {
|
|
1896
|
+
cleanup();
|
|
1897
|
+
resolve(value);
|
|
1898
|
+
}, (error) => {
|
|
1899
|
+
cleanup();
|
|
1900
|
+
reject(error);
|
|
1901
|
+
});
|
|
1989
1902
|
});
|
|
1990
1903
|
}
|
|
1904
|
+
/** @internal */
|
|
1905
|
+
function validateOptions(options) {
|
|
1906
|
+
if (typeof options.namespace !== "string" || !options.namespace.trim()) throw new TypeError("namespace must be nonempty");
|
|
1907
|
+
if (!Number.isSafeInteger(options.schemaVersion) || options.schemaVersion <= 0) throw new TypeError("schemaVersion must be a positive safe integer");
|
|
1908
|
+
if (!Number.isFinite(options.maxAge) || options.maxAge < 0) throw new TypeError("maxAge must be finite and nonnegative");
|
|
1909
|
+
for (const name of [
|
|
1910
|
+
"key",
|
|
1911
|
+
"decode",
|
|
1912
|
+
"load"
|
|
1913
|
+
]) if (typeof options[name] !== "function") throw new TypeError(`${name} must be a function`);
|
|
1914
|
+
}
|
|
1915
|
+
/** @internal */
|
|
1916
|
+
function createCache(options, backend, session) {
|
|
1917
|
+
const states = /* @__PURE__ */ new Map();
|
|
1918
|
+
let disposed = false;
|
|
1919
|
+
let scopeBlocked = false;
|
|
1920
|
+
let disposal;
|
|
1921
|
+
let io = Promise.resolve();
|
|
1922
|
+
function storage(action) {
|
|
1923
|
+
const result = io.then(action);
|
|
1924
|
+
io = result.catch(() => {});
|
|
1925
|
+
return result;
|
|
1926
|
+
}
|
|
1927
|
+
function checkOpen() {
|
|
1928
|
+
if (disposed) throw new Error("Cache is disposed");
|
|
1929
|
+
}
|
|
1930
|
+
function identity(query) {
|
|
1931
|
+
checkOpen();
|
|
1932
|
+
const key = options.key(query);
|
|
1933
|
+
if (typeof key !== "string") throw new TypeError("key must return a string");
|
|
1934
|
+
return key;
|
|
1935
|
+
}
|
|
1936
|
+
function stateFor(key) {
|
|
1937
|
+
let state = states.get(key);
|
|
1938
|
+
if (!state) {
|
|
1939
|
+
state = {
|
|
1940
|
+
controller: new AbortController(),
|
|
1941
|
+
blocked: scopeBlocked
|
|
1942
|
+
};
|
|
1943
|
+
states.set(key, state);
|
|
1944
|
+
}
|
|
1945
|
+
return state;
|
|
1946
|
+
}
|
|
1947
|
+
function checkState(state) {
|
|
1948
|
+
if (state.controller.signal.aborted) throw abortError();
|
|
1949
|
+
}
|
|
1950
|
+
function fresh(entry) {
|
|
1951
|
+
const now = Date.now();
|
|
1952
|
+
return !entry.invalidated && entry.validatedAt <= now && now - entry.validatedAt < options.maxAge;
|
|
1953
|
+
}
|
|
1954
|
+
function restore(value, previous) {
|
|
1955
|
+
return {
|
|
1956
|
+
...value.meta,
|
|
1957
|
+
data: value.body ? options.decode(value.body.data) : previous.data
|
|
1958
|
+
};
|
|
1959
|
+
}
|
|
1960
|
+
async function read(key, state) {
|
|
1961
|
+
if (state.entry && fresh(state.entry)) return state.entry;
|
|
1962
|
+
const entry = await storage(async () => {
|
|
1963
|
+
checkState(state);
|
|
1964
|
+
if (state.blocked) return state.entry;
|
|
1965
|
+
try {
|
|
1966
|
+
const value = await backend.read(key, state.entry?.version);
|
|
1967
|
+
return value ? restore(value, state.entry) : state.entry;
|
|
1968
|
+
} catch {
|
|
1969
|
+
return state.entry;
|
|
1970
|
+
}
|
|
1971
|
+
});
|
|
1972
|
+
checkState(state);
|
|
1973
|
+
state.entry = entry;
|
|
1974
|
+
return entry;
|
|
1975
|
+
}
|
|
1976
|
+
function schedule(key, query, state, force) {
|
|
1977
|
+
const job = {
|
|
1978
|
+
started: false,
|
|
1979
|
+
force
|
|
1980
|
+
};
|
|
1981
|
+
job.promise = (async () => {
|
|
1982
|
+
const previous = await read(key, state);
|
|
1983
|
+
checkState(state);
|
|
1984
|
+
if (!job.force && previous && fresh(previous)) return previous.data;
|
|
1985
|
+
job.started = true;
|
|
1986
|
+
const result = await options.load(query, {
|
|
1987
|
+
etag: previous?.etag ?? null,
|
|
1988
|
+
signal: state.controller.signal
|
|
1989
|
+
});
|
|
1990
|
+
checkState(state);
|
|
1991
|
+
let entry;
|
|
1992
|
+
if (result.modified) entry = {
|
|
1993
|
+
data: result.data,
|
|
1994
|
+
etag: result.etag,
|
|
1995
|
+
version: crypto.getRandomValues(/* @__PURE__ */ new Uint32Array(4)).join("-"),
|
|
1996
|
+
validatedAt: Date.now(),
|
|
1997
|
+
invalidated: false
|
|
1998
|
+
};
|
|
1999
|
+
else {
|
|
2000
|
+
if (!previous) throw new Error("Load protocol error: unmodified response without cached data");
|
|
2001
|
+
entry = {
|
|
2002
|
+
...previous,
|
|
2003
|
+
etag: result.etag === void 0 ? previous.etag : result.etag,
|
|
2004
|
+
validatedAt: Date.now(),
|
|
2005
|
+
invalidated: false
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
await storage(async () => {
|
|
2009
|
+
checkState(state);
|
|
2010
|
+
try {
|
|
2011
|
+
if (await backend.write(key, entry, result.modified)) state.blocked = false;
|
|
2012
|
+
} catch {
|
|
2013
|
+
state.blocked = true;
|
|
2014
|
+
}
|
|
2015
|
+
checkState(state);
|
|
2016
|
+
state.entry = entry;
|
|
2017
|
+
});
|
|
2018
|
+
checkState(state);
|
|
2019
|
+
return entry.data;
|
|
2020
|
+
})();
|
|
2021
|
+
state.job = job;
|
|
2022
|
+
const release = () => {
|
|
2023
|
+
state.job = void 0;
|
|
2024
|
+
};
|
|
2025
|
+
job.promise.then(release, release);
|
|
2026
|
+
return job;
|
|
2027
|
+
}
|
|
2028
|
+
function refresh(key, query, state, force) {
|
|
2029
|
+
const active = state.job;
|
|
2030
|
+
if (!active) return schedule(key, query, state, force).promise;
|
|
2031
|
+
if (!force) return active.promise;
|
|
2032
|
+
if (!active.started) {
|
|
2033
|
+
active.force = true;
|
|
2034
|
+
return active.promise;
|
|
2035
|
+
}
|
|
2036
|
+
if (!state.queued) {
|
|
2037
|
+
const start = () => {
|
|
2038
|
+
checkState(state);
|
|
2039
|
+
state.queued = void 0;
|
|
2040
|
+
return schedule(key, query, state, true).promise;
|
|
2041
|
+
};
|
|
2042
|
+
state.queued = active.promise.then(start, start);
|
|
2043
|
+
}
|
|
2044
|
+
return state.queued;
|
|
2045
|
+
}
|
|
2046
|
+
function reset(key, keep) {
|
|
2047
|
+
const old = states.get(key);
|
|
2048
|
+
const state = {
|
|
2049
|
+
controller: new AbortController(),
|
|
2050
|
+
blocked: true
|
|
2051
|
+
};
|
|
2052
|
+
if (keep && old?.entry) state.entry = {
|
|
2053
|
+
...old.entry,
|
|
2054
|
+
invalidated: true
|
|
2055
|
+
};
|
|
2056
|
+
states.set(key, state);
|
|
2057
|
+
return {
|
|
2058
|
+
state,
|
|
2059
|
+
cancel: () => old?.controller.abort()
|
|
2060
|
+
};
|
|
2061
|
+
}
|
|
2062
|
+
function resetAll() {
|
|
2063
|
+
const old = [...states.values()];
|
|
2064
|
+
states.clear();
|
|
2065
|
+
const barrier = {};
|
|
2066
|
+
scopeBlocked = barrier;
|
|
2067
|
+
return {
|
|
2068
|
+
barrier,
|
|
2069
|
+
cancel() {
|
|
2070
|
+
for (const state of old) state.controller.abort();
|
|
2071
|
+
}
|
|
2072
|
+
};
|
|
2073
|
+
}
|
|
2074
|
+
return {
|
|
2075
|
+
async get(query, getOptions = {}) {
|
|
2076
|
+
const key = identity(query);
|
|
2077
|
+
if (getOptions.signal?.aborted) throw abortError();
|
|
2078
|
+
const state = stateFor(key);
|
|
2079
|
+
if (!getOptions.revalidate && state.entry && fresh(state.entry)) return state.entry.data;
|
|
2080
|
+
return wait(refresh(key, query, state, getOptions.revalidate === true), state.controller.signal, getOptions.signal);
|
|
2081
|
+
},
|
|
2082
|
+
async peek(query) {
|
|
2083
|
+
const key = identity(query);
|
|
2084
|
+
const state = stateFor(key);
|
|
2085
|
+
const entry = await wait(read(key, state), state.controller.signal);
|
|
2086
|
+
return entry ? {
|
|
2087
|
+
data: entry.data,
|
|
2088
|
+
etag: entry.etag,
|
|
2089
|
+
validatedAt: entry.validatedAt,
|
|
2090
|
+
fresh: fresh(entry)
|
|
2091
|
+
} : void 0;
|
|
2092
|
+
},
|
|
2093
|
+
async invalidate(query) {
|
|
2094
|
+
const key = identity(query);
|
|
2095
|
+
const canRestore = !(states.get(key)?.blocked ?? scopeBlocked);
|
|
2096
|
+
const { state, cancel } = reset(key, true);
|
|
2097
|
+
const cleanup = storage(async () => {
|
|
2098
|
+
const value = await backend.invalidate(key);
|
|
2099
|
+
if (canRestore) state.blocked = false;
|
|
2100
|
+
if (canRestore && !state.controller.signal.aborted && !state.entry && value) try {
|
|
2101
|
+
state.entry = restore(value);
|
|
2102
|
+
} catch {}
|
|
2103
|
+
});
|
|
2104
|
+
cancel();
|
|
2105
|
+
await cleanup;
|
|
2106
|
+
},
|
|
2107
|
+
async remove(query) {
|
|
2108
|
+
const key = identity(query);
|
|
2109
|
+
const { state, cancel } = reset(key, false);
|
|
2110
|
+
const cleanup = storage(async () => {
|
|
2111
|
+
await backend.remove(key);
|
|
2112
|
+
state.blocked = false;
|
|
2113
|
+
});
|
|
2114
|
+
cancel();
|
|
2115
|
+
await cleanup;
|
|
2116
|
+
},
|
|
2117
|
+
async clear() {
|
|
2118
|
+
checkOpen();
|
|
2119
|
+
const { barrier, cancel } = resetAll();
|
|
2120
|
+
const cleanup = storage(async () => {
|
|
2121
|
+
await backend.clear(false);
|
|
2122
|
+
if (scopeBlocked === barrier) scopeBlocked = false;
|
|
2123
|
+
for (const state of states.values()) if (state.blocked === barrier) state.blocked = false;
|
|
2124
|
+
});
|
|
2125
|
+
cancel();
|
|
2126
|
+
await cleanup;
|
|
2127
|
+
},
|
|
2128
|
+
dispose() {
|
|
2129
|
+
if (!disposal) {
|
|
2130
|
+
disposed = true;
|
|
2131
|
+
const { cancel } = resetAll();
|
|
2132
|
+
disposal = storage(async () => {
|
|
2133
|
+
if (session) await backend.clear(true);
|
|
2134
|
+
});
|
|
2135
|
+
disposal = disposal.catch((error) => {
|
|
2136
|
+
disposal = void 0;
|
|
2137
|
+
throw error;
|
|
2138
|
+
});
|
|
2139
|
+
cancel();
|
|
2140
|
+
}
|
|
2141
|
+
return disposal;
|
|
2142
|
+
}
|
|
2143
|
+
};
|
|
2144
|
+
}
|
|
2145
|
+
function object(value) {
|
|
2146
|
+
return typeof value === "object" && value !== null;
|
|
2147
|
+
}
|
|
2148
|
+
function metadata(value) {
|
|
2149
|
+
if (!object(value) || typeof value.version !== "string" || !value.version || !(value.etag === null || typeof value.etag === "string") || typeof value.invalidated !== "boolean") return void 0;
|
|
2150
|
+
const validTime = typeof value.validatedAt === "number" && Number.isFinite(value.validatedAt) && value.validatedAt >= 0;
|
|
2151
|
+
return {
|
|
2152
|
+
version: value.version,
|
|
2153
|
+
etag: value.etag,
|
|
2154
|
+
validatedAt: validTime ? value.validatedAt : 0,
|
|
2155
|
+
invalidated: !validTime || value.invalidated === true
|
|
2156
|
+
};
|
|
2157
|
+
}
|
|
2158
|
+
function stored(meta, body) {
|
|
2159
|
+
if (!object(body) || body.version !== meta.version || !Object.hasOwn(body, "data")) return void 0;
|
|
2160
|
+
return {
|
|
2161
|
+
meta,
|
|
2162
|
+
body: { data: body.data }
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
var storagePrefix = "@oomol-lab/resource-cache:";
|
|
2166
|
+
/** Delimit identity fields without ambiguous string concatenation. @internal */
|
|
2167
|
+
function scope(namespace) {
|
|
2168
|
+
return storagePrefix + JSON.stringify(namespace);
|
|
2169
|
+
}
|
|
2170
|
+
/** @internal */
|
|
2171
|
+
function sessionScope(namespace, sessionId) {
|
|
2172
|
+
return storagePrefix + JSON.stringify([namespace, sessionId]);
|
|
2173
|
+
}
|
|
2174
|
+
/** @internal */
|
|
2175
|
+
function persistentStorage(namespace, schemaVersion) {
|
|
2176
|
+
const useStore = createStore("@oomol-lab/resource-cache", "records");
|
|
2177
|
+
const prefix = `${scope(namespace)}:${schemaVersion}:`;
|
|
2178
|
+
const identity = (key, part) => prefix + JSON.stringify([key, part]);
|
|
2179
|
+
function transaction(mode, work) {
|
|
2180
|
+
return useStore(mode, (store) => new Promise((resolve, reject) => {
|
|
2181
|
+
const tx = store.transaction;
|
|
2182
|
+
let value;
|
|
2183
|
+
let failure;
|
|
2184
|
+
tx.oncomplete = () => resolve(value);
|
|
2185
|
+
tx.onabort = () => reject(failure ?? tx.error);
|
|
2186
|
+
const guard = (fn) => {
|
|
2187
|
+
try {
|
|
2188
|
+
fn();
|
|
2189
|
+
} catch (error) {
|
|
2190
|
+
failure = error;
|
|
2191
|
+
tx.abort();
|
|
2192
|
+
}
|
|
2193
|
+
};
|
|
2194
|
+
const read = (request, fn) => {
|
|
2195
|
+
request.onsuccess = () => guard(() => fn(request.result));
|
|
2196
|
+
};
|
|
2197
|
+
guard(() => work(store, read, (result) => {
|
|
2198
|
+
value = result;
|
|
2199
|
+
}));
|
|
2200
|
+
}));
|
|
2201
|
+
}
|
|
2202
|
+
return {
|
|
2203
|
+
read(key, version) {
|
|
2204
|
+
return transaction("readonly", (store, read, result) => {
|
|
2205
|
+
read(store.get(identity(key, "meta")), (raw) => {
|
|
2206
|
+
const meta = metadata(raw);
|
|
2207
|
+
if (!meta) return;
|
|
2208
|
+
if (meta.version === version) {
|
|
2209
|
+
result({ meta });
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2212
|
+
read(store.get(identity(key, "body")), (body) => result(stored(meta, body)));
|
|
2213
|
+
});
|
|
2214
|
+
});
|
|
2215
|
+
},
|
|
2216
|
+
write(key, entry, modified) {
|
|
2217
|
+
return transaction("readwrite", (store, read, result) => {
|
|
2218
|
+
const { data, ...meta } = entry;
|
|
2219
|
+
if (modified) {
|
|
2220
|
+
store.put(meta, identity(key, "meta"));
|
|
2221
|
+
store.put({
|
|
2222
|
+
version: meta.version,
|
|
2223
|
+
data
|
|
2224
|
+
}, identity(key, "body"));
|
|
2225
|
+
result(true);
|
|
2226
|
+
} else read(store.get(identity(key, "meta")), (raw) => {
|
|
2227
|
+
const matches = metadata(raw)?.version === meta.version;
|
|
2228
|
+
if (matches) store.put(meta, identity(key, "meta"));
|
|
2229
|
+
result(matches);
|
|
2230
|
+
});
|
|
2231
|
+
});
|
|
2232
|
+
},
|
|
2233
|
+
invalidate(key) {
|
|
2234
|
+
return transaction("readwrite", (store, read, result) => {
|
|
2235
|
+
read(store.get(identity(key, "meta")), (raw) => {
|
|
2236
|
+
const meta = metadata(raw);
|
|
2237
|
+
if (!meta) return;
|
|
2238
|
+
meta.invalidated = true;
|
|
2239
|
+
store.put(meta, identity(key, "meta"));
|
|
2240
|
+
read(store.get(identity(key, "body")), (body) => result(stored(meta, body)));
|
|
2241
|
+
});
|
|
2242
|
+
});
|
|
2243
|
+
},
|
|
2244
|
+
remove(key) {
|
|
2245
|
+
return transaction("readwrite", (store) => {
|
|
2246
|
+
store.delete(identity(key, "meta"));
|
|
2247
|
+
store.delete(identity(key, "body"));
|
|
2248
|
+
});
|
|
2249
|
+
},
|
|
2250
|
+
clear() {
|
|
2251
|
+
return transaction("readwrite", (store, read) => {
|
|
2252
|
+
read(store.getAllKeys(), (keys) => {
|
|
2253
|
+
for (const key of keys) if (typeof key === "string" && key.startsWith(prefix)) store.delete(key);
|
|
2254
|
+
});
|
|
2255
|
+
});
|
|
2256
|
+
}
|
|
2257
|
+
};
|
|
2258
|
+
}
|
|
2259
|
+
/** @internal */
|
|
2260
|
+
function sessionStorageBackend(namespace, schemaVersion, sessionId) {
|
|
2261
|
+
const base = `${sessionScope(namespace, sessionId)}:`;
|
|
2262
|
+
const prefix = `${base}${schemaVersion}:`;
|
|
2263
|
+
const identity = (key) => prefix + JSON.stringify(key);
|
|
2264
|
+
const record = (key) => {
|
|
2265
|
+
const text = globalThis.sessionStorage.getItem(identity(key));
|
|
2266
|
+
if (text === null) return void 0;
|
|
2267
|
+
const raw = JSON.parse(text);
|
|
2268
|
+
const meta = metadata(raw);
|
|
2269
|
+
return meta ? stored(meta, raw) : void 0;
|
|
2270
|
+
};
|
|
2271
|
+
return {
|
|
2272
|
+
async read(key, version) {
|
|
2273
|
+
const value = record(key);
|
|
2274
|
+
if (value && value.meta.version === version) return { meta: value.meta };
|
|
2275
|
+
return value;
|
|
2276
|
+
},
|
|
2277
|
+
async write(key, entry, modified) {
|
|
2278
|
+
if (modified) {
|
|
2279
|
+
globalThis.sessionStorage.setItem(identity(key), JSON.stringify(entry));
|
|
2280
|
+
return true;
|
|
2281
|
+
} else {
|
|
2282
|
+
const value = record(key);
|
|
2283
|
+
if (value?.meta.version === entry.version) {
|
|
2284
|
+
const { data: _data, ...meta } = entry;
|
|
2285
|
+
globalThis.sessionStorage.setItem(identity(key), JSON.stringify({
|
|
2286
|
+
...meta,
|
|
2287
|
+
data: value.body.data
|
|
2288
|
+
}));
|
|
2289
|
+
return true;
|
|
2290
|
+
}
|
|
2291
|
+
return false;
|
|
2292
|
+
}
|
|
2293
|
+
},
|
|
2294
|
+
async invalidate(key) {
|
|
2295
|
+
const value = record(key);
|
|
2296
|
+
if (value) {
|
|
2297
|
+
value.meta.invalidated = true;
|
|
2298
|
+
globalThis.sessionStorage.setItem(identity(key), JSON.stringify({
|
|
2299
|
+
...value.meta,
|
|
2300
|
+
...value.body
|
|
2301
|
+
}));
|
|
2302
|
+
}
|
|
2303
|
+
return value;
|
|
2304
|
+
},
|
|
2305
|
+
async remove(key) {
|
|
2306
|
+
globalThis.sessionStorage.removeItem(identity(key));
|
|
2307
|
+
},
|
|
2308
|
+
async clear(allVersions) {
|
|
2309
|
+
const storage = globalThis.sessionStorage;
|
|
2310
|
+
const matches = [];
|
|
2311
|
+
for (let i = 0; i < storage.length; i++) {
|
|
2312
|
+
const key = storage.key(i);
|
|
2313
|
+
if (key.startsWith(allVersions ? base : prefix)) matches.push(key);
|
|
2314
|
+
}
|
|
2315
|
+
for (const key of matches) storage.removeItem(key);
|
|
2316
|
+
}
|
|
2317
|
+
};
|
|
2318
|
+
}
|
|
2319
|
+
/** Create an IndexedDB cache. Storage failures preserve successful network results. */
|
|
2320
|
+
function createPersistentCache(options) {
|
|
2321
|
+
validateOptions(options);
|
|
2322
|
+
return createCache({ ...options }, persistentStorage(options.namespace, options.schemaVersion), false);
|
|
2323
|
+
}
|
|
2324
|
+
/** Create a login-scoped sessionStorage cache. Data must survive JSON serialization and decoding. */
|
|
2325
|
+
function createSessionCache(options) {
|
|
2326
|
+
validateOptions(options);
|
|
2327
|
+
if (typeof options.sessionId !== "string" || !options.sessionId.trim()) throw new TypeError("sessionId must be nonempty");
|
|
2328
|
+
return createCache({ ...options }, sessionStorageBackend(options.namespace, options.schemaVersion, options.sessionId), true);
|
|
2329
|
+
}
|
|
1991
2330
|
//#endregion
|
|
1992
|
-
//#region
|
|
1993
|
-
|
|
1994
|
-
var
|
|
1995
|
-
|
|
1996
|
-
|
|
2331
|
+
//#region ../../node_modules/.bun/@oomol-lab+resource-cache@0.1.4/node_modules/@oomol-lab/resource-cache/dist/oomol.mjs
|
|
2332
|
+
/** Namespaces reserved for the OOMOL response factories. */
|
|
2333
|
+
var oomolNamespaces = {
|
|
2334
|
+
providers: "oomol:providers",
|
|
2335
|
+
actions: "oomol:actions",
|
|
2336
|
+
appCatalog: "oomol:app-catalog",
|
|
2337
|
+
connections: "oomol:connections"
|
|
1997
2338
|
};
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2339
|
+
/** Join identity fields without nesting JSON in the storage key. */
|
|
2340
|
+
function readableKey(...parts) {
|
|
2341
|
+
return parts.map((part) => encodeURIComponent(String(part)).replaceAll("%3A", ":")).join("/");
|
|
2342
|
+
}
|
|
2343
|
+
var singletonRegistrySymbol = Symbol.for("oomol-lab.resource-cache.oomol-singletons");
|
|
2344
|
+
var singletonCaches = Reflect.get(globalThis, singletonRegistrySymbol) ?? (() => {
|
|
2345
|
+
const registry = /* @__PURE__ */ new Map();
|
|
2346
|
+
Reflect.set(globalThis, singletonRegistrySymbol, registry);
|
|
2347
|
+
return registry;
|
|
2348
|
+
})();
|
|
2349
|
+
function createOomolCache(resource, options, query) {
|
|
2350
|
+
const environment = validateOomolOptions(options);
|
|
2351
|
+
const { load } = options;
|
|
2352
|
+
const key = readableKey(query.locale);
|
|
2353
|
+
return createPersistentCache({
|
|
2354
|
+
namespace: readableKey(resource, environment),
|
|
2355
|
+
schemaVersion: options.schemaVersion,
|
|
2356
|
+
maxAge: options.maxAge,
|
|
2357
|
+
key: () => key,
|
|
2358
|
+
decode: options.decode,
|
|
2359
|
+
load: (_query, validation) => load({ ...query }, validation)
|
|
2360
|
+
});
|
|
2361
|
+
}
|
|
2362
|
+
function createConnectionsCacheInternal(options, validated) {
|
|
2363
|
+
const { environment, ownerId } = validated;
|
|
2364
|
+
const { load } = options;
|
|
2365
|
+
const key = readableKey(ownerId);
|
|
2366
|
+
return createSessionCache({
|
|
2367
|
+
namespace: readableKey(oomolNamespaces.connections, environment),
|
|
2368
|
+
schemaVersion: options.schemaVersion,
|
|
2369
|
+
maxAge: options.maxAge,
|
|
2370
|
+
sessionId: options.sessionId,
|
|
2371
|
+
key: () => key,
|
|
2372
|
+
decode: options.decode,
|
|
2373
|
+
load: (_query, validation) => load({ ownerId }, validation)
|
|
2374
|
+
});
|
|
2375
|
+
}
|
|
2376
|
+
function validateOomolOptions(options) {
|
|
2377
|
+
const environment = normalizeEnvironment(options.environment);
|
|
2378
|
+
if (typeof options.locale !== "string" || !options.locale.trim()) throw new TypeError("locale must be nonempty");
|
|
2379
|
+
if (typeof options.load !== "function") throw new TypeError("load must be a function");
|
|
2380
|
+
return environment;
|
|
2381
|
+
}
|
|
2382
|
+
function normalizeEnvironment(value) {
|
|
2383
|
+
const environment = value === void 0 ? "production" : value;
|
|
2384
|
+
if (typeof environment !== "string" || !environment.trim()) throw new TypeError("environment must be nonempty");
|
|
2385
|
+
return environment;
|
|
2386
|
+
}
|
|
2387
|
+
function normalizeOwnerId(value) {
|
|
2388
|
+
if (typeof value !== "string" || !value.trim()) throw new TypeError("ownerId must be nonempty");
|
|
2389
|
+
return value;
|
|
2390
|
+
}
|
|
2391
|
+
function validateConnectionsOptions(options) {
|
|
2392
|
+
const environment = normalizeEnvironment(options.environment);
|
|
2393
|
+
if (typeof options.sessionId !== "string" || !options.sessionId.trim()) throw new TypeError("sessionId must be nonempty");
|
|
2394
|
+
const ownerId = normalizeOwnerId(options.ownerId);
|
|
2395
|
+
if (typeof options.load !== "function") throw new TypeError("load must be a function");
|
|
2001
2396
|
return {
|
|
2002
|
-
|
|
2003
|
-
|
|
2397
|
+
environment,
|
|
2398
|
+
ownerId
|
|
2004
2399
|
};
|
|
2005
2400
|
}
|
|
2401
|
+
/** Create an IndexedDB cache for the account-independent GET /v1/providers response, keyed by environment and locale. */
|
|
2402
|
+
function createProvidersCacheInternal(options) {
|
|
2403
|
+
return createOomolCache(oomolNamespaces.providers, options, { locale: options.locale });
|
|
2404
|
+
}
|
|
2405
|
+
/** Create an IndexedDB cache for account-independent GET /v1/actions?service=…, keyed by environment, locale and service. */
|
|
2406
|
+
function createActionsCacheInternal(options) {
|
|
2407
|
+
const environment = validateOomolOptions(options);
|
|
2408
|
+
const { locale, load } = options;
|
|
2409
|
+
return createPersistentCache({
|
|
2410
|
+
namespace: readableKey(oomolNamespaces.actions, environment),
|
|
2411
|
+
schemaVersion: options.schemaVersion,
|
|
2412
|
+
maxAge: options.maxAge,
|
|
2413
|
+
key: (service) => {
|
|
2414
|
+
if (typeof service !== "string" || !service.trim()) throw new TypeError("service must be nonempty");
|
|
2415
|
+
return readableKey(locale, service);
|
|
2416
|
+
},
|
|
2417
|
+
decode: options.decode,
|
|
2418
|
+
load: (service, validation) => load({
|
|
2419
|
+
locale,
|
|
2420
|
+
service
|
|
2421
|
+
}, validation)
|
|
2422
|
+
});
|
|
2423
|
+
}
|
|
2424
|
+
function singletonKey(resource, options, query, sessionId) {
|
|
2425
|
+
const environment = normalizeEnvironment(options.environment);
|
|
2426
|
+
return sessionId === void 0 ? readableKey(resource, environment, options.schemaVersion, ...query) : readableKey(resource, environment, options.schemaVersion, sessionId, ...query);
|
|
2427
|
+
}
|
|
2428
|
+
function getSingleton(key, create) {
|
|
2429
|
+
const existing = singletonCaches.get(key);
|
|
2430
|
+
if (existing) return existing;
|
|
2431
|
+
const cache = create();
|
|
2432
|
+
let disposal;
|
|
2433
|
+
const singleton = {
|
|
2434
|
+
...cache,
|
|
2435
|
+
dispose() {
|
|
2436
|
+
if (!disposal) disposal = cache.dispose().then(() => {
|
|
2437
|
+
singletonCaches.delete(key);
|
|
2438
|
+
}, (error) => {
|
|
2439
|
+
disposal = void 0;
|
|
2440
|
+
throw error;
|
|
2441
|
+
});
|
|
2442
|
+
return disposal;
|
|
2443
|
+
}
|
|
2444
|
+
};
|
|
2445
|
+
singletonCaches.set(key, singleton);
|
|
2446
|
+
return singleton;
|
|
2447
|
+
}
|
|
2448
|
+
/** Return the shared Providers cache for one environment, locale and schema version. */
|
|
2449
|
+
function getProvidersCache(options) {
|
|
2450
|
+
const query = { locale: options.locale };
|
|
2451
|
+
return getSingleton(singletonKey(oomolNamespaces.providers, options, [query.locale]), () => createProvidersCacheInternal(options));
|
|
2452
|
+
}
|
|
2453
|
+
/** Return the shared Actions cache for one environment, locale and schema version. */
|
|
2454
|
+
function getActionsCache(options) {
|
|
2455
|
+
const query = { locale: options.locale };
|
|
2456
|
+
return getSingleton(singletonKey(oomolNamespaces.actions, options, [query.locale]), () => createActionsCacheInternal(options));
|
|
2457
|
+
}
|
|
2458
|
+
/** Return the shared sessionStorage cache for one login session and owner scope. */
|
|
2459
|
+
function getConnectionsCache(options) {
|
|
2460
|
+
const validated = validateConnectionsOptions(options);
|
|
2461
|
+
const query = { ownerId: validated.ownerId };
|
|
2462
|
+
return getSingleton(singletonKey(oomolNamespaces.connections, options, [query.ownerId], options.sessionId), () => createConnectionsCacheInternal(options, validated));
|
|
2463
|
+
}
|
|
2006
2464
|
//#endregion
|
|
2007
2465
|
//#region src/connector/common/actionSchema.ts
|
|
2008
2466
|
function connectorActionPorts(inputSchema, outputSchema) {
|
|
@@ -2176,46 +2634,178 @@ function action(source, providers) {
|
|
|
2176
2634
|
}
|
|
2177
2635
|
//#endregion
|
|
2178
2636
|
//#region src/workbench/browser/runtime/stores/catalogStores.ts
|
|
2179
|
-
|
|
2637
|
+
var catalogMaxAge = {
|
|
2638
|
+
providers: 3e5,
|
|
2639
|
+
actions: 3e4,
|
|
2640
|
+
connections: 3e4
|
|
2641
|
+
};
|
|
2642
|
+
var identity = (...parts) => JSON.stringify(parts);
|
|
2643
|
+
function proxyCatalogPath(kind, flowId, locale, service) {
|
|
2644
|
+
return `/v1/connector/proxy/${kind}?${new URLSearchParams({
|
|
2645
|
+
...flowId == null ? {} : { flowId },
|
|
2646
|
+
...service == null ? {} : { service },
|
|
2647
|
+
locale
|
|
2648
|
+
})}`;
|
|
2649
|
+
}
|
|
2650
|
+
function mapCache(cache, toValue, toSnapshot, query) {
|
|
2651
|
+
return {
|
|
2652
|
+
get: async (value, options) => toValue(await cache.get(query(value), options)),
|
|
2653
|
+
peek: async (value) => {
|
|
2654
|
+
const snapshot = await cache.peek(query(value));
|
|
2655
|
+
return snapshot == null ? void 0 : {
|
|
2656
|
+
...snapshot,
|
|
2657
|
+
data: toSnapshot(snapshot.data)
|
|
2658
|
+
};
|
|
2659
|
+
},
|
|
2660
|
+
invalidate: (value) => cache.invalidate(query(value)),
|
|
2661
|
+
remove: (value) => cache.remove(query(value)),
|
|
2662
|
+
clear: () => cache.clear(),
|
|
2663
|
+
dispose: () => cache.dispose()
|
|
2664
|
+
};
|
|
2665
|
+
}
|
|
2666
|
+
function providerCacheValue(value) {
|
|
2667
|
+
return proxyResponse(value);
|
|
2668
|
+
}
|
|
2669
|
+
function actionCacheValue(value) {
|
|
2670
|
+
return proxyResponse(value);
|
|
2671
|
+
}
|
|
2672
|
+
function connectionsCacheValue(value) {
|
|
2180
2673
|
const source = record(value);
|
|
2181
|
-
if (source.
|
|
2182
|
-
|
|
2674
|
+
if (source.success === true && Array.isArray(source.data)) return source;
|
|
2675
|
+
if (source.version == 1 && Array.isArray(source.connections)) return {
|
|
2676
|
+
success: true,
|
|
2677
|
+
message: "",
|
|
2678
|
+
data: source.connections,
|
|
2679
|
+
meta: { summary: {
|
|
2680
|
+
providerCount: 0,
|
|
2681
|
+
connectableProviderCount: 0,
|
|
2682
|
+
connectedProviderCount: 0,
|
|
2683
|
+
activeConnectedProviderCount: 0,
|
|
2684
|
+
connectedAppCount: source.connections.length,
|
|
2685
|
+
activeConnectedAppCount: source.connections.length,
|
|
2686
|
+
filteredAppCount: source.connections.length
|
|
2687
|
+
} }
|
|
2688
|
+
};
|
|
2689
|
+
return invalidResponse();
|
|
2183
2690
|
}
|
|
2184
|
-
|
|
2185
|
-
|
|
2691
|
+
function connectionsAsProxy(value) {
|
|
2692
|
+
return value.data.map(connection);
|
|
2693
|
+
}
|
|
2694
|
+
/** Shared cache construction for one Workbench session. */
|
|
2695
|
+
var CacheFactory = class {
|
|
2696
|
+
#caches = /* @__PURE__ */ new Set();
|
|
2697
|
+
#entries = /* @__PURE__ */ new Map();
|
|
2698
|
+
#disposed = false;
|
|
2699
|
+
constructor(scope) {
|
|
2700
|
+
this.scope = scope;
|
|
2701
|
+
}
|
|
2702
|
+
cache(key, create, owned = true) {
|
|
2703
|
+
let entry = this.#entries.get(key);
|
|
2704
|
+
if (entry == null) {
|
|
2705
|
+
entry = create().then((cache) => {
|
|
2706
|
+
if (owned) {
|
|
2707
|
+
if (this.#disposed) cache.dispose();
|
|
2708
|
+
else this.#caches.add(cache);
|
|
2709
|
+
}
|
|
2710
|
+
return cache;
|
|
2711
|
+
});
|
|
2712
|
+
this.#entries.set(key, entry);
|
|
2713
|
+
}
|
|
2714
|
+
return entry;
|
|
2715
|
+
}
|
|
2716
|
+
async dispose() {
|
|
2717
|
+
this.#disposed = true;
|
|
2718
|
+
await Promise.all([...this.#caches].map((cache) => cache.dispose()));
|
|
2719
|
+
this.#caches.clear();
|
|
2720
|
+
this.#entries.clear();
|
|
2721
|
+
}
|
|
2722
|
+
get environment() {
|
|
2723
|
+
return this.scope.environment ?? "production";
|
|
2724
|
+
}
|
|
2725
|
+
get sessionId() {
|
|
2726
|
+
return this.scope.sessionId;
|
|
2727
|
+
}
|
|
2728
|
+
get connectorOwnerId() {
|
|
2729
|
+
return this.scope.connectorOwnerId;
|
|
2730
|
+
}
|
|
2731
|
+
};
|
|
2732
|
+
/** Each entry owns one complete upstream response; views are derived below. */
|
|
2186
2733
|
var ProxyStore = class {
|
|
2187
|
-
|
|
2734
|
+
#factory;
|
|
2735
|
+
constructor(client, kind, scope) {
|
|
2188
2736
|
this.client = client;
|
|
2189
2737
|
this.kind = kind;
|
|
2190
|
-
this.options = options;
|
|
2191
2738
|
this.entries = /* @__PURE__ */ new Map();
|
|
2739
|
+
this.#factory = new CacheFactory(scope);
|
|
2192
2740
|
}
|
|
2193
|
-
get(flowId, locale, service, force = false) {
|
|
2194
|
-
const
|
|
2195
|
-
...flowId == null ? {} : { flowId },
|
|
2196
|
-
...service == null ? {} : { service },
|
|
2197
|
-
...locale == null ? {} : { locale }
|
|
2198
|
-
});
|
|
2199
|
-
const path = `/v1/connector/proxy/${this.kind}${params.size ? `?${params}` : ""}`;
|
|
2741
|
+
get(flowId, locale = "en", service, force = false) {
|
|
2742
|
+
const path = proxyCatalogPath(this.kind, flowId, locale, service);
|
|
2200
2743
|
let entry = this.entries.get(path);
|
|
2201
2744
|
if (entry == null) {
|
|
2202
|
-
|
|
2203
|
-
const cacheParams = new URLSearchParams(params);
|
|
2204
|
-
cacheParams.delete("flowId");
|
|
2205
|
-
const persistence = catalogPersistence(this.options, this.kind, cacheParams.toString());
|
|
2206
|
-
entry = new Resource((etag, signal) => this.client.readProxyCatalog({
|
|
2207
|
-
path,
|
|
2208
|
-
decode
|
|
2209
|
-
}, etag, signal), this.kind == "providers" ? 3e5 : 3e4, persistence == null ? void 0 : {
|
|
2210
|
-
...persistence,
|
|
2211
|
-
decode
|
|
2212
|
-
});
|
|
2745
|
+
entry = new CacheResource(() => this.#cache(flowId, locale, service, path), void 0, false, catalogMaxAge[this.kind]);
|
|
2213
2746
|
this.entries.set(path, entry);
|
|
2214
2747
|
}
|
|
2215
2748
|
return entry.get(force);
|
|
2216
2749
|
}
|
|
2750
|
+
async #cache(flowId, locale, service, path) {
|
|
2751
|
+
const ownerId = this.#factory.connectorOwnerId;
|
|
2752
|
+
const key = JSON.stringify([
|
|
2753
|
+
this.kind,
|
|
2754
|
+
flowId ?? null,
|
|
2755
|
+
locale,
|
|
2756
|
+
service ?? null,
|
|
2757
|
+
ownerId ?? null
|
|
2758
|
+
]);
|
|
2759
|
+
return this.#factory.cache(key, async () => {
|
|
2760
|
+
if (ownerId != null) {
|
|
2761
|
+
if (this.kind == "providers") return mapCache(getProvidersCache({
|
|
2762
|
+
environment: this.#factory.environment,
|
|
2763
|
+
locale,
|
|
2764
|
+
schemaVersion: 1,
|
|
2765
|
+
maxAge: catalogMaxAge.providers,
|
|
2766
|
+
decode: providerCacheValue,
|
|
2767
|
+
load: async (_query, validation) => {
|
|
2768
|
+
return await this.client.readProxyCatalog({
|
|
2769
|
+
path,
|
|
2770
|
+
decode: providerCacheValue
|
|
2771
|
+
}, validation.etag, validation.signal);
|
|
2772
|
+
}
|
|
2773
|
+
}), (value) => value, (value) => value, () => void 0);
|
|
2774
|
+
return mapCache(getActionsCache({
|
|
2775
|
+
environment: this.#factory.environment,
|
|
2776
|
+
locale,
|
|
2777
|
+
schemaVersion: 1,
|
|
2778
|
+
maxAge: catalogMaxAge.actions,
|
|
2779
|
+
decode: actionCacheValue,
|
|
2780
|
+
load: async ({ service: requestedService }, validation) => {
|
|
2781
|
+
return await this.client.readProxyCatalog({
|
|
2782
|
+
path: proxyCatalogPath("actions", flowId, locale, requestedService),
|
|
2783
|
+
decode: actionCacheValue
|
|
2784
|
+
}, validation.etag, validation.signal);
|
|
2785
|
+
}
|
|
2786
|
+
}), (value) => value, (value) => value, () => service ?? "");
|
|
2787
|
+
}
|
|
2788
|
+
return createSessionCache({
|
|
2789
|
+
namespace: JSON.stringify([
|
|
2790
|
+
"open-flow:connector-proxy",
|
|
2791
|
+
this.#factory.environment,
|
|
2792
|
+
this.kind,
|
|
2793
|
+
flowId ?? null
|
|
2794
|
+
]),
|
|
2795
|
+
schemaVersion: 1,
|
|
2796
|
+
sessionId: this.#factory.sessionId,
|
|
2797
|
+
maxAge: this.kind == "providers" ? catalogMaxAge.providers : catalogMaxAge.actions,
|
|
2798
|
+
key: () => JSON.stringify([locale, service ?? null]),
|
|
2799
|
+
decode: proxyResponse,
|
|
2800
|
+
load: async (_query, validation) => this.client.readProxyCatalog({
|
|
2801
|
+
path,
|
|
2802
|
+
decode: proxyResponse
|
|
2803
|
+
}, validation.etag, validation.signal)
|
|
2804
|
+
});
|
|
2805
|
+
}, ownerId == null);
|
|
2806
|
+
}
|
|
2217
2807
|
retryFailed() {
|
|
2218
|
-
for (const entry of this.entries.values()) if (entry.state.value.error != null) entry.refresh();
|
|
2808
|
+
for (const entry of this.entries.values()) if (entry.state.value.error != null) entry.refresh(true);
|
|
2219
2809
|
}
|
|
2220
2810
|
refreshFlow(flowId) {
|
|
2221
2811
|
for (const [path, entry] of this.entries) if (new URL(path, "https://open-flow.invalid").searchParams.get("flowId") == flowId) entry.refresh(true);
|
|
@@ -2223,6 +2813,7 @@ var ProxyStore = class {
|
|
|
2223
2813
|
dispose() {
|
|
2224
2814
|
for (const entry of this.entries.values()) entry.dispose();
|
|
2225
2815
|
this.entries.clear();
|
|
2816
|
+
this.#factory.dispose();
|
|
2226
2817
|
}
|
|
2227
2818
|
};
|
|
2228
2819
|
var Views = class {
|
|
@@ -2273,8 +2864,8 @@ var Views = class {
|
|
|
2273
2864
|
};
|
|
2274
2865
|
var ProviderStore = class {
|
|
2275
2866
|
#views = new Views();
|
|
2276
|
-
constructor(client,
|
|
2277
|
-
this.raw = new ProxyStore(client, "providers",
|
|
2867
|
+
constructor(client, scope) {
|
|
2868
|
+
this.raw = new ProxyStore(client, "providers", scope);
|
|
2278
2869
|
}
|
|
2279
2870
|
get(flowId, locale = "en", force = false) {
|
|
2280
2871
|
return this.#views.get(identity(flowId, locale), [this.raw.get(flowId, locale, void 0, force)], (response) => response.data.map((item) => provider(item, response.meta?.iconSprite)));
|
|
@@ -2291,33 +2882,17 @@ var ProviderStore = class {
|
|
|
2291
2882
|
}
|
|
2292
2883
|
};
|
|
2293
2884
|
var ConnectionStore = class {
|
|
2294
|
-
#storage = {
|
|
2295
|
-
get: async (key) => {
|
|
2296
|
-
const raw = (this.options?.storage ?? window.sessionStorage).getItem(key);
|
|
2297
|
-
return raw == null ? void 0 : JSON.parse(raw);
|
|
2298
|
-
},
|
|
2299
|
-
set: async (key, value) => {
|
|
2300
|
-
(this.options?.storage ?? window.sessionStorage).setItem(key, JSON.stringify(value));
|
|
2301
|
-
}
|
|
2302
|
-
};
|
|
2303
2885
|
#entries = /* @__PURE__ */ new Map();
|
|
2304
2886
|
#views = /* @__PURE__ */ new Map();
|
|
2305
|
-
|
|
2887
|
+
#factory;
|
|
2888
|
+
constructor(client, scope) {
|
|
2306
2889
|
this.client = client;
|
|
2307
|
-
this
|
|
2890
|
+
this.#factory = new CacheFactory(scope);
|
|
2308
2891
|
}
|
|
2309
2892
|
get(serviceId, flowId, force = false) {
|
|
2310
2893
|
let entry = this.#entries.get(flowId);
|
|
2311
2894
|
if (entry == null) {
|
|
2312
|
-
|
|
2313
|
-
entry = new Resource((etag, signal) => this.client.readCatalog(query, etag, signal), 3e4, this.options == null ? void 0 : {
|
|
2314
|
-
key: `open-flow:connections:v1:${query.path}`,
|
|
2315
|
-
storage: this.#storage,
|
|
2316
|
-
decode: (value) => {
|
|
2317
|
-
if (!Array.isArray(value)) return invalidResponse();
|
|
2318
|
-
return value.map(connection);
|
|
2319
|
-
}
|
|
2320
|
-
});
|
|
2895
|
+
entry = new CacheResource(() => this.#cache(flowId), void 0, false, catalogMaxAge.connections);
|
|
2321
2896
|
this.#entries.set(flowId, entry);
|
|
2322
2897
|
}
|
|
2323
2898
|
const source = entry.get(force);
|
|
@@ -2333,8 +2908,54 @@ var ConnectionStore = class {
|
|
|
2333
2908
|
}
|
|
2334
2909
|
return view;
|
|
2335
2910
|
}
|
|
2911
|
+
async #cache(flowId) {
|
|
2912
|
+
const query = allConnectorConnectionsQuery(flowId);
|
|
2913
|
+
const ownerId = this.#factory.connectorOwnerId;
|
|
2914
|
+
const key = JSON.stringify([
|
|
2915
|
+
"connections",
|
|
2916
|
+
flowId ?? null,
|
|
2917
|
+
ownerId ?? null
|
|
2918
|
+
]);
|
|
2919
|
+
return this.#factory.cache(key, async () => {
|
|
2920
|
+
if (ownerId != null) return mapCache(getConnectionsCache({
|
|
2921
|
+
environment: this.#factory.environment,
|
|
2922
|
+
sessionId: this.#factory.sessionId,
|
|
2923
|
+
ownerId,
|
|
2924
|
+
schemaVersion: 1,
|
|
2925
|
+
maxAge: catalogMaxAge.connections,
|
|
2926
|
+
decode: connectionsCacheValue,
|
|
2927
|
+
load: async (_query, validation) => {
|
|
2928
|
+
const result = await this.client.readCatalog(query, validation.etag, validation.signal);
|
|
2929
|
+
return result.modified ? {
|
|
2930
|
+
modified: true,
|
|
2931
|
+
data: connectionsCacheValue({
|
|
2932
|
+
version: 1,
|
|
2933
|
+
connections: result.data
|
|
2934
|
+
}),
|
|
2935
|
+
etag: result.etag
|
|
2936
|
+
} : result;
|
|
2937
|
+
}
|
|
2938
|
+
}), connectionsAsProxy, connectionsAsProxy, () => void 0);
|
|
2939
|
+
return createSessionCache({
|
|
2940
|
+
namespace: JSON.stringify([
|
|
2941
|
+
"open-flow:connections",
|
|
2942
|
+
this.#factory.environment,
|
|
2943
|
+
flowId ?? null
|
|
2944
|
+
]),
|
|
2945
|
+
schemaVersion: 1,
|
|
2946
|
+
sessionId: this.#factory.sessionId,
|
|
2947
|
+
maxAge: catalogMaxAge.connections,
|
|
2948
|
+
key: () => "all",
|
|
2949
|
+
decode: (value) => {
|
|
2950
|
+
if (!Array.isArray(value)) return invalidResponse();
|
|
2951
|
+
return value.map(connection);
|
|
2952
|
+
},
|
|
2953
|
+
load: async (_query, validation) => this.client.readCatalog(query, validation.etag, validation.signal)
|
|
2954
|
+
});
|
|
2955
|
+
}, ownerId == null);
|
|
2956
|
+
}
|
|
2336
2957
|
retryFailed() {
|
|
2337
|
-
for (const entry of this.#entries.values()) if (entry.state.value.error != null) entry.refresh();
|
|
2958
|
+
for (const entry of this.#entries.values()) if (entry.state.value.error != null) entry.refresh(true);
|
|
2338
2959
|
}
|
|
2339
2960
|
refreshFlow(flowId) {
|
|
2340
2961
|
this.#entries.get(flowId)?.refresh(true);
|
|
@@ -2344,6 +2965,7 @@ var ConnectionStore = class {
|
|
|
2344
2965
|
this.#views.clear();
|
|
2345
2966
|
for (const entry of this.#entries.values()) entry.dispose();
|
|
2346
2967
|
this.#entries.clear();
|
|
2968
|
+
this.#factory.dispose();
|
|
2347
2969
|
}
|
|
2348
2970
|
};
|
|
2349
2971
|
var ActionStore = class {
|
|
@@ -2352,10 +2974,10 @@ var ActionStore = class {
|
|
|
2352
2974
|
#details = /* @__PURE__ */ new Map();
|
|
2353
2975
|
#searches = /* @__PURE__ */ new Set();
|
|
2354
2976
|
#searchSessions = /* @__PURE__ */ new WeakMap();
|
|
2355
|
-
constructor(client, providers,
|
|
2977
|
+
constructor(client, providers, scope) {
|
|
2356
2978
|
this.client = client;
|
|
2357
2979
|
this.providers = providers;
|
|
2358
|
-
this.#raw = new ProxyStore(client, "actions",
|
|
2980
|
+
this.#raw = new ProxyStore(client, "actions", scope);
|
|
2359
2981
|
}
|
|
2360
2982
|
get(serviceId, flowId, locale = "en", force = false) {
|
|
2361
2983
|
return this.#views.get(identity(flowId, serviceId, locale), [this.#raw.get(flowId, locale, serviceId, force), this.providers.raw.get(flowId, locale)], (actions, providers) => actions.data.flatMap((item) => {
|
|
@@ -2399,7 +3021,6 @@ var ActionStore = class {
|
|
|
2399
3021
|
q: query.trim(),
|
|
2400
3022
|
locale
|
|
2401
3023
|
});
|
|
2402
|
-
const key = params.toString();
|
|
2403
3024
|
let entries = this.#searchSessions.get(signal);
|
|
2404
3025
|
if (entries == null) {
|
|
2405
3026
|
entries = /* @__PURE__ */ new Map();
|
|
@@ -2414,21 +3035,38 @@ var ActionStore = class {
|
|
|
2414
3035
|
this.#searchSessions.delete(signal);
|
|
2415
3036
|
}, { once: true });
|
|
2416
3037
|
}
|
|
3038
|
+
const key = params.toString();
|
|
2417
3039
|
const cached = entries.get(key);
|
|
2418
3040
|
if (cached != null) {
|
|
2419
|
-
cached.refresh();
|
|
3041
|
+
cached.refresh(true);
|
|
2420
3042
|
return cached;
|
|
2421
3043
|
}
|
|
2422
|
-
const
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
3044
|
+
const cache = createSessionCache({
|
|
3045
|
+
namespace: JSON.stringify(["open-flow:action-search", crypto.randomUUID()]),
|
|
3046
|
+
schemaVersion: 1,
|
|
3047
|
+
sessionId: "search",
|
|
3048
|
+
maxAge: 0,
|
|
3049
|
+
key: () => "result",
|
|
3050
|
+
decode: (value) => {
|
|
3051
|
+
if (!Array.isArray(value)) return invalidResponse();
|
|
3052
|
+
return value.map(connectorActionMetadata);
|
|
3053
|
+
},
|
|
3054
|
+
load: async (_query, validation) => this.client.readCatalog({
|
|
3055
|
+
path: `/v1/connector/action-metadata?${params}`,
|
|
3056
|
+
decode: (value) => {
|
|
3057
|
+
const source = record(value);
|
|
3058
|
+
if (source.version != 1 || !Array.isArray(source.actions)) return invalidResponse();
|
|
3059
|
+
return source.actions.map(connectorActionMetadata);
|
|
3060
|
+
}
|
|
3061
|
+
}, validation.etag, validation.signal)
|
|
3062
|
+
});
|
|
3063
|
+
const result = new CacheResource(async () => cache, void 0, true, 0);
|
|
3064
|
+
if (signal.aborted) result.dispose();
|
|
2427
3065
|
else {
|
|
2428
|
-
entries.set(key,
|
|
2429
|
-
this.#searches.add(
|
|
3066
|
+
entries.set(key, result);
|
|
3067
|
+
this.#searches.add(result);
|
|
2430
3068
|
}
|
|
2431
|
-
return
|
|
3069
|
+
return result;
|
|
2432
3070
|
}
|
|
2433
3071
|
retryFailed() {
|
|
2434
3072
|
this.#raw.retryFailed();
|
|
@@ -2446,10 +3084,10 @@ var ActionStore = class {
|
|
|
2446
3084
|
}
|
|
2447
3085
|
};
|
|
2448
3086
|
var CatalogStores = class {
|
|
2449
|
-
constructor(client,
|
|
2450
|
-
this.providers = new ProviderStore(client,
|
|
2451
|
-
this.actions = new ActionStore(client, this.providers,
|
|
2452
|
-
this.connections = new ConnectionStore(client,
|
|
3087
|
+
constructor(client, scope = { sessionId: crypto.randomUUID() }) {
|
|
3088
|
+
this.providers = new ProviderStore(client, scope);
|
|
3089
|
+
this.actions = new ActionStore(client, this.providers, scope);
|
|
3090
|
+
this.connections = new ConnectionStore(client, scope);
|
|
2453
3091
|
}
|
|
2454
3092
|
dispose() {
|
|
2455
3093
|
this.actions.dispose();
|
|
@@ -2625,6 +3263,26 @@ var ConnectorAccessStore = class {
|
|
|
2625
3263
|
}
|
|
2626
3264
|
return false;
|
|
2627
3265
|
}
|
|
3266
|
+
allowedTriggerCandidates(providerId, triggerId) {
|
|
3267
|
+
return this.#state.value.candidates[providerId]?.candidates.filter((candidate) => candidate.permissions == null || candidate.permissions.allTriggers || candidate.permissions.triggerIds.includes(triggerId));
|
|
3268
|
+
}
|
|
3269
|
+
async filterTriggerConnections(flowId, definition, connections) {
|
|
3270
|
+
if (this.#disposed || flowId != this.#flowId) return [];
|
|
3271
|
+
const access = this.#state.value.access;
|
|
3272
|
+
if (access?.mode == "implicit") return connections;
|
|
3273
|
+
if (access == null) return [];
|
|
3274
|
+
await this.loadCandidates([definition.provider]);
|
|
3275
|
+
if (this.#disposed || flowId != this.#flowId) return [];
|
|
3276
|
+
const candidates = this.allowedTriggerCandidates(definition.provider, definition.key);
|
|
3277
|
+
if (candidates == null) return [];
|
|
3278
|
+
const allowed = new Set(candidates.map((candidate) => candidate.connectionId));
|
|
3279
|
+
const filtered = connections.filter((connection) => allowed.has(connection.connectionId));
|
|
3280
|
+
if (!filtered.some((connection) => connection.status == "active") && connections.some((connection) => connection.status == "active")) this.setNotice({
|
|
3281
|
+
kind: "error",
|
|
3282
|
+
message: this.i18n.t("connectorAccess.noAvailablePermissions")
|
|
3283
|
+
});
|
|
3284
|
+
return filtered;
|
|
3285
|
+
}
|
|
2628
3286
|
async setService(providerId, selected) {
|
|
2629
3287
|
const flowId = this.#flowId;
|
|
2630
3288
|
const access = this.#state.value.access;
|
|
@@ -2829,8 +3487,9 @@ var ConnectorStore = class {
|
|
|
2829
3487
|
};
|
|
2830
3488
|
this.provideAddNodeOptionChoices = (optionId, signal) => {
|
|
2831
3489
|
const service = optionId.slice(19);
|
|
2832
|
-
const
|
|
2833
|
-
const
|
|
3490
|
+
const flowId = this.#workspace.$.flowId.value;
|
|
3491
|
+
const source = this.data.actions.get(service, flowId, this.#language);
|
|
3492
|
+
const providers = this.data.providers.get(flowId, this.#language);
|
|
2834
3493
|
return scopedValue(signal, (get) => {
|
|
2835
3494
|
const state = get(source);
|
|
2836
3495
|
const provider = get(providers).data?.find((item) => item.serviceId == service);
|
|
@@ -2961,12 +3620,22 @@ var ConnectorStore = class {
|
|
|
2961
3620
|
this.#actionIds.set([]);
|
|
2962
3621
|
this.#services.set([]);
|
|
2963
3622
|
}
|
|
3623
|
+
retryAction(actionId) {
|
|
3624
|
+
const flowId = this.#workspace.$.flowId.value;
|
|
3625
|
+
if (flowId == null || this.#disposed) return;
|
|
3626
|
+
const actionState = this.data.actions.detail(actionId, flowId, this.#language, true);
|
|
3627
|
+
if (this.data.providers.get(flowId, this.#language).value.error != null) this.data.providers.get(flowId, this.#language, true);
|
|
3628
|
+
if (actionState.value.data?.authenticated !== false) this.data.connections.refreshFlow(flowId);
|
|
3629
|
+
}
|
|
2964
3630
|
async resolveAction(actionId) {
|
|
2965
3631
|
const flowId = this.#workspace.$.flowId.value;
|
|
2966
3632
|
if (flowId == null || this.#disposed) throw new Error("Connector Action cannot be resolved without an active Flow.");
|
|
3633
|
+
const actionState = this.data.actions.detail(actionId, flowId, this.#language);
|
|
3634
|
+
await Promise.resolve();
|
|
3635
|
+
const action = await resourceValue(actionState, void 0, true);
|
|
3636
|
+
const connectionState = action.authenticated ? this.data.connections.get(action.serviceId, flowId) : void 0;
|
|
2967
3637
|
await Promise.resolve();
|
|
2968
|
-
const
|
|
2969
|
-
const connections = action.authenticated ? await resourceValue(this.data.connections.get(action.serviceId, flowId), void 0, true) : [];
|
|
3638
|
+
const connections = connectionState == null ? [] : await resourceValue(connectionState, void 0, true);
|
|
2970
3639
|
this.#remember(this.#actionIds, [actionId]);
|
|
2971
3640
|
if (action.authenticated) this.#remember(this.#services, [action.serviceId]);
|
|
2972
3641
|
return {
|
|
@@ -3143,9 +3812,9 @@ var ConnectorStore = class {
|
|
|
3143
3812
|
var TriggerCatalogStore = class {
|
|
3144
3813
|
#language;
|
|
3145
3814
|
#entries;
|
|
3146
|
-
constructor(client, language,
|
|
3815
|
+
constructor(client, language, environment = "production") {
|
|
3147
3816
|
this.client = client;
|
|
3148
|
-
this.
|
|
3817
|
+
this.environment = environment;
|
|
3149
3818
|
this.#entries = /* @__PURE__ */ new Map();
|
|
3150
3819
|
this.retry = () => {
|
|
3151
3820
|
this.get(true);
|
|
@@ -3161,14 +3830,18 @@ var TriggerCatalogStore = class {
|
|
|
3161
3830
|
if (data.locale != locale) throw new Error("Unexpected Trigger catalog language.");
|
|
3162
3831
|
return data;
|
|
3163
3832
|
};
|
|
3164
|
-
const
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3833
|
+
const cache = createPersistentCache({
|
|
3834
|
+
namespace: JSON.stringify(["open-flow:trigger-catalog", this.environment]),
|
|
3835
|
+
schemaVersion: 1,
|
|
3836
|
+
maxAge: 3e5,
|
|
3837
|
+
key: () => locale,
|
|
3838
|
+
decode,
|
|
3839
|
+
load: async (_query, validation) => this.client.readCatalog({
|
|
3840
|
+
path: `/v1/trigger-keys/catalog?locale=${encodeURIComponent(locale)}`,
|
|
3841
|
+
decode
|
|
3842
|
+
}, validation.etag, validation.signal)
|
|
3171
3843
|
});
|
|
3844
|
+
entry = new CacheResource(async () => cache, void 0, true, 3e5);
|
|
3172
3845
|
this.#entries.set(locale, entry);
|
|
3173
3846
|
}
|
|
3174
3847
|
return entry;
|
|
@@ -3247,7 +3920,7 @@ var TriggerStore = class {
|
|
|
3247
3920
|
this.#disposed = false;
|
|
3248
3921
|
this.browseAddNodeOptions = (signal) => this.#options("", signal);
|
|
3249
3922
|
this.provideAddNodeOptions = (searchTerm, signal) => this.#options(searchTerm, signal);
|
|
3250
|
-
this.catalog = new TriggerCatalogStore(client, resolveUiLanguage([i18n.lang]), host);
|
|
3923
|
+
this.catalog = new TriggerCatalogStore(client, resolveUiLanguage([i18n.lang]), host.cacheEnvironment);
|
|
3251
3924
|
this.#client = client;
|
|
3252
3925
|
this.#host = host;
|
|
3253
3926
|
this.#i18n = i18n;
|
|
@@ -3262,7 +3935,7 @@ var TriggerStore = class {
|
|
|
3262
3935
|
if (trigger.kind != "poll" && trigger.kind != "integration") return { authorizationPending: false };
|
|
3263
3936
|
const connections = current == null ? void 0 : get(workspace.catalogs.connections.get(current.provider, get(workspace.$.flowId))).data;
|
|
3264
3937
|
const catalog = connections == null ? void 0 : connectionCatalog(connections);
|
|
3265
|
-
const connectionError = current == null ? void 0 : get(workspace.catalogs.connections.get(current.provider, get(workspace.$.flowId))).error;
|
|
3938
|
+
const connectionError = current == null ? void 0 : state.connectionError?.provider == current.provider ? new Error(state.connectionError.message) : get(workspace.catalogs.connections.get(current.provider, get(workspace.$.flowId))).error;
|
|
3266
3939
|
return {
|
|
3267
3940
|
activeConnections: catalog?.active,
|
|
3268
3941
|
authorizationPending: state.authorizationProvider == current?.provider,
|
|
@@ -3628,6 +4301,7 @@ function inverseFlowChanges(content, operations) {
|
|
|
3628
4301
|
value: operation.before
|
|
3629
4302
|
});
|
|
3630
4303
|
break;
|
|
4304
|
+
case "task.openapi.set":
|
|
3631
4305
|
case "task.agent.set":
|
|
3632
4306
|
restore.push({
|
|
3633
4307
|
...operation,
|
|
@@ -4699,10 +5373,11 @@ var WorkspaceStore = class {
|
|
|
4699
5373
|
#pendingRepair;
|
|
4700
5374
|
#stopCatalogWatch;
|
|
4701
5375
|
#stopFlowWatch;
|
|
4702
|
-
constructor(client, setNotice, identity = createAuthoringId, i18n = createI18n(), runChanged = () => {}, catalogs = new CatalogStores(client), flowCreated = () => {}, accessChanged = () => {}) {
|
|
5376
|
+
constructor(client, setNotice, identity = createAuthoringId, i18n = createI18n(), runChanged = () => {}, catalogs = new CatalogStores(client), flowCreated = () => {}, accessChanged = () => {}, filterTriggerConnections) {
|
|
4703
5377
|
this.catalogs = catalogs;
|
|
4704
5378
|
this.flowCreated = flowCreated;
|
|
4705
5379
|
this.accessChanged = accessChanged;
|
|
5380
|
+
this.filterTriggerConnections = filterTriggerConnections;
|
|
4706
5381
|
this.#draftSession = new Latest();
|
|
4707
5382
|
this.#history = new CanvasHistory();
|
|
4708
5383
|
this.history$ = this.#history.state$;
|
|
@@ -5022,9 +5697,10 @@ var WorkspaceStore = class {
|
|
|
5022
5697
|
if (intent.kind == "provider-trigger" && intent.connectionId == null) {
|
|
5023
5698
|
try {
|
|
5024
5699
|
const connections = await resourceValue(this.catalogs.connections.get(intent.definition.provider, draft.flowId));
|
|
5700
|
+
const allowed = this.filterTriggerConnections == null ? connections : await this.filterTriggerConnections(draft.flowId, intent.definition, connections);
|
|
5025
5701
|
intent = {
|
|
5026
5702
|
...intent,
|
|
5027
|
-
connectionId: connectionCatalog(
|
|
5703
|
+
connectionId: connectionCatalog(allowed).preferred?.connectionId
|
|
5028
5704
|
};
|
|
5029
5705
|
} catch (error) {
|
|
5030
5706
|
if (!this.#disposed && this.#model.value.draft == draft) this.#setNotice(errorNotice(error, this.#i18n.t));
|
|
@@ -5268,6 +5944,9 @@ var WorkspaceStore = class {
|
|
|
5268
5944
|
position
|
|
5269
5945
|
}));
|
|
5270
5946
|
}
|
|
5947
|
+
loadOpenApiDocument(url, signal) {
|
|
5948
|
+
return this.#client.loadOpenApiDocument(url, signal);
|
|
5949
|
+
}
|
|
5271
5950
|
async saveTaskSettings(nodeId, settings) {
|
|
5272
5951
|
const revision = this.$.revision.value;
|
|
5273
5952
|
const target = this.#model.value.target;
|
|
@@ -5817,7 +6496,7 @@ var WorkbenchStore = class {
|
|
|
5817
6496
|
#openingCreatedFlow;
|
|
5818
6497
|
#stopAccessReaction;
|
|
5819
6498
|
#accessLoading;
|
|
5820
|
-
constructor(client, preferences, identity = randomId, i18n = createI18n(), host = blockedExternalPages, variables = true) {
|
|
6499
|
+
constructor(client, preferences, identity = randomId, i18n = createI18n(), host = blockedExternalPages, variables = true, cacheSessionId = crypto.randomUUID()) {
|
|
5821
6500
|
this.#externalRuns = new Latest();
|
|
5822
6501
|
this.#notice = val();
|
|
5823
6502
|
this.#variableNames = val([]);
|
|
@@ -5851,9 +6530,16 @@ var WorkbenchStore = class {
|
|
|
5851
6530
|
this.workspace = new WorkspaceStore(client, setNotice, createAuthoringId, i18n, (event) => {
|
|
5852
6531
|
if (event.kind == "run.created") this.#followExternalRun(client, event);
|
|
5853
6532
|
else this.runs.changed(event.runId);
|
|
5854
|
-
}, new CatalogStores(client,
|
|
6533
|
+
}, new CatalogStores(client, {
|
|
6534
|
+
sessionId: cacheSessionId,
|
|
6535
|
+
environment: host.cacheEnvironment,
|
|
6536
|
+
connectorOwnerId: host.connectorOwnerId
|
|
6537
|
+
}), (flowId) => void this.#openCreatedFlow(flowId), (flowId) => {
|
|
5855
6538
|
this.connectorAccess.changed(flowId);
|
|
5856
6539
|
this.workspace.catalogs.refreshFlow(flowId);
|
|
6540
|
+
}, async (flowId, definition, connections) => {
|
|
6541
|
+
await this.#accessLoading;
|
|
6542
|
+
return this.connectorAccess.filterTriggerConnections(flowId, definition, connections);
|
|
5857
6543
|
});
|
|
5858
6544
|
this.#stopAccessReaction = this.workspace.$.flowId.reaction((flowId) => {
|
|
5859
6545
|
this.#accessLoading = this.connectorAccess.load(flowId);
|
|
@@ -6229,7 +6915,7 @@ var WorkbenchStore = class {
|
|
|
6229
6915
|
};
|
|
6230
6916
|
//#endregion
|
|
6231
6917
|
//#region src/workbench/browser/runtime/openFlowWorkbench.tsx
|
|
6232
|
-
var FlowWorkspace = lazy(() => import("./flowWorkspace-
|
|
6918
|
+
var FlowWorkspace = lazy(() => import("./flowWorkspace-CoT_ewLX.js"));
|
|
6233
6919
|
function OpenFlowSessionGate({ action, description, error, onSubmit, onTokenChange, pending = false, title, token, tokenLabel }) {
|
|
6234
6920
|
const hasToken = token != null && tokenLabel != null && onTokenChange != null;
|
|
6235
6921
|
const tokenValue = token ?? "";
|
|
@@ -6364,17 +7050,17 @@ function Workbench({ catalogWidth, createFlow, createFlowDisabled, createFlowFie
|
|
|
6364
7050
|
})
|
|
6365
7051
|
});
|
|
6366
7052
|
}
|
|
6367
|
-
function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField, flowBadges, connectionHref, host, hrefFor, language, location, onConfigureConnector, onManageConnectorAccess, onLanguageChange, onNavigate, preferences, theme, variables = true }) {
|
|
7053
|
+
function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField, flowBadges, connectionHref, host, hrefFor, language, location, onConfigureConnector, onManageConnectorAccess, onLanguageChange, onNavigate, preferences, sessionKey, theme, variables = true }) {
|
|
6368
7054
|
const navigate = useRef(onNavigate);
|
|
6369
7055
|
navigate.current = onNavigate;
|
|
6370
7056
|
const [{ i18n, navigation, store }] = useState(() => {
|
|
6371
7057
|
const workbenchI18n = createI18n(language);
|
|
6372
7058
|
const workbenchStore = new WorkbenchStore(new WorkbenchClient((input, init) => host.request(input, init), (flowId, listener) => host.subscribeFlow(flowId, listener), (listener) => host.subscribeFlowCatalog(listener)), preferences, randomId, workbenchI18n, {
|
|
6373
7059
|
openExternalPage: (resolveUrl) => host.openExternalPage(resolveUrl),
|
|
6374
|
-
|
|
6375
|
-
|
|
7060
|
+
cacheEnvironment: host.cacheEnvironment,
|
|
7061
|
+
connectorOwnerId: host.connectorOwnerId,
|
|
6376
7062
|
resolveActor: actorResolver(host, globalThis.location?.origin)
|
|
6377
|
-
}, variables);
|
|
7063
|
+
}, variables, sessionKey);
|
|
6378
7064
|
return {
|
|
6379
7065
|
i18n: workbenchI18n,
|
|
6380
7066
|
navigation: new NavigationStore(workbenchStore, location, (nextLocation, options) => navigate.current(nextLocation, options)),
|
|
@@ -6445,7 +7131,10 @@ function Session({ catalogWidth, createFlow, createFlowDisabled, createFlowField
|
|
|
6445
7131
|
});
|
|
6446
7132
|
}
|
|
6447
7133
|
function OpenFlowWorkbench({ sessionKey, ...props }) {
|
|
6448
|
-
return /* @__PURE__ */ jsx(Session, {
|
|
7134
|
+
return /* @__PURE__ */ jsx(Session, {
|
|
7135
|
+
sessionKey,
|
|
7136
|
+
...props
|
|
7137
|
+
}, `${sessionKey}:${props.host.connectorOwnerId ?? ""}`);
|
|
6449
7138
|
}
|
|
6450
7139
|
//#endregion
|
|
6451
7140
|
export { EventSourcesPage, OpenFlowSessionGate, OpenFlowWorkbench, isUiLanguage as isWorkbenchLanguage, resolveUiLanguage as resolveWorkbenchLanguage, uiLanguageNames as workbenchLanguageNames, uiLanguages as workbenchLanguages };
|