@oomol-lab/open-flow 0.1.0-beta.61 → 0.1.0-beta.62

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.
@@ -1,7 +1,7 @@
1
1
  import { o as __toESM, t as __commonJSMin } from "./rolldown-runtime-CEgmsyvS.js";
2
2
  import { a as derive, i as compute, l as val, r as combine, t as arrayShallowEqual } from "./dist-bO8nvHFH.js";
3
3
  import { l as useTranslate, o as I18nProvider } from "./dist-BFmpkX4P.js";
4
- import { $n as fastComponentRef, $r as itemPress, $t as useDirection, A as decisionTask, An as useImplicitActiveTrigger, Ar as ownerDocument, At as useCompositeListItem, B as nextNodeName, Bi as isHTMLElement$1, Bn as useFloatingParentNodeId, Br as useOnMount, Ci as useRenderElement, Cn as useHoverFloatingInteraction, Ct as SelectGroup, Di as warn, Dn as createInitialPopupStoreState, Dt as SelectValue, Ei as NOOP, Et as SelectTrigger, F as schemaObject, Fi as SafeReact, Fn as useClick, Fr as useTransitionStatus, Gn as DROPDOWN_COLLISION_AVOIDANCE, H as normalizeNodeName, Hn as FloatingTreeStore, Hr as createChangeEventDetails, Ii as useStableCallback, In as FloatingFocusManager, Ir as useOpenChangeComplete, J as nodeInputMappings, Jr as focusOut, Jt as usePositioner, K as conditionInputPorts, Kn as POPUP_COLLISION_AVOIDANCE, Kr as closePress, Kt as useToolbarRootContext, Li as useRefWithInit, Ln as FloatingNode, Lr as useAnimationsFinished, Lt as COMPOSITE_KEYS, Mi as formatErrorMessage, Mn as useTriggerDataForwarding, N as comparePorts, Ni as mergeProps, Nn as useTriggerRegistration, Nr as Check, Oi as useMergedRefs, On as popupStoreSelectors, Ot as Separator, P as matchesSchema, Pi as useIsoLayoutEffect, Pn as useDismiss, Pr as createLucideIcon, Qn as fastComponent, Qt as adaptiveOrigin, R as applyFlowChanges$1, Ri as getParentNode, Rn as FloatingTree, Si as clsx, Sn as useHoverReferenceInteraction, St as SelectContent, Ti as EMPTY_OBJECT, Tn as useSyncedFloatingRootContext, Tr as contains, U as portsByHandle, Un as FloatingPortal, Vi as isLastTraversableNode, Vn as useFloatingTree, Vr as useValueChanged, Wn as CLICK_TRIGGER_IDENTIFIER, Wr as cancelOpen, Xt as InternalBackdrop, Yn as ReactStore, Yr as imperativeAction, Yt as getDisabledMountTransitionStyles, Z as otherwiseOutput, Zt as useAnchorPositioning, _i as useControlled, _n as safePolygon, _t as union, ai as triggerHover, an as triggerOpenStateMapping, ar as Label, at as array, bi as cn, bn as useListNavigation, bt as Select, ci as useFormContext, cr as useTimeout, ct as int, d as TooltipContent, di as useBaseUiId, dr as getTabbableBeforeElement, dt as literal, en as CompositeList, et as authoringDefinitionSchemas, fi as useId$1, fr as isOutsideEvent, ft as number, gi as visuallyHiddenInput, gt as string$1, hi as visuallyHidden, ht as strictObject, in as pressableTriggerOpenStateMapping, ir as useOnFirstRender, it as _enum, ji as useCompositeRootContext, jn as useOpenStateTransitions, ki as useButton, kn as PopupTriggerMap, kr as isMac, li as useRegisterFieldControl, lr as getNextTabbable, lt as json$2, mi as fieldValidityMapping, mt as record$2, nn as getPseudoElementBounds, nr as createSelector, or as Input, ot as boolean, p as TooltipTrigger, pt as object$1, qn as FocusGuard, qt as useAnchoredPopupScrollLock, ri as siblingOpen, rn as popupStateMapping, rt as webhookSupportsBody, si as useLabelableContext, sn as useOpenInteractionType, sr as Timeout, st as discriminatedUnion, ti as none, tn as inertValue, tt as decodeRevisionContent, u as Tooltip, ui as useFieldRootContext, ur as getTabbableAfterElement, ut as lazy$1, vi as Button, vn as useTypeahead, vt as format, wi as EMPTY_ARRAY, wn as useFocus, wt as SelectItem, xi as cva, xn as useInteractions, yi as buttonVariants, yn as useRole, yt as dequal, z as isSchemaKeyword, zn as useFloatingNodeId, zr as transitionStatusMapping } from "./icons-DVJvrj1H.js";
4
+ import { $ as otherwiseOutput, $n as fastComponent, $t as adaptiveOrigin, Ai as useButton, An as PopupTriggerMap, Ar as isMac, B as applyFlowChanges$1, Bn as useFloatingNodeId, Br as transitionStatusMapping, Ci as clsx, Cn as useHoverReferenceInteraction, Ct as SelectContent, D as authoringDefinitionSchemas, Di as NOOP, Dt as SelectTrigger, Ei as EMPTY_OBJECT, En as useSyncedFloatingRootContext, Er as contains, F as comparePorts, Fi as useIsoLayoutEffect, Fn as useDismiss, Fr as createLucideIcon, G as portsByHandle, Gn as CLICK_TRIGGER_IDENTIFIER, Gr as cancelOpen, H as nextNodeName, Hi as isLastTraversableNode, Hn as useFloatingTree, Hr as useValueChanged, I as matchesSchema, Ii as SafeReact, In as useClick, Ir as useTransitionStatus, J as conditionInputPorts, Jn as FocusGuard, Jt as useAnchoredPopupScrollLock, Kn as DROPDOWN_COLLISION_AVOIDANCE, L as schemaObject, Li as useStableCallback, Ln as FloatingFocusManager, Lr as useOpenChangeComplete, M as decisionTask, Mi as useCompositeRootContext, Mn as useOpenStateTransitions, Ni as formatErrorMessage, Nn as useTriggerDataForwarding, O as decodeRevisionContent, Oi as warn, On as createInitialPopupStoreState, Ot as SelectValue, Pi as mergeProps, Pn as useTriggerRegistration, Pr as Check, Qt as useAnchorPositioning, Ri as useRefWithInit, Rn as FloatingNode, Rr as useAnimationsFinished, Rt as COMPOSITE_KEYS, Si as cva, Sn as useInteractions, Ti as EMPTY_ARRAY, Tn as useFocus, Tt as SelectItem, Un as FloatingTreeStore, Ur as createChangeEventDetails, V as isSchemaKeyword, Vi as isHTMLElement$1, Vn as useFloatingParentNodeId, Vr as useOnMount, W as normalizeNodeName, Wn as FloatingPortal, X as nodeInputMappings, Xn as ReactStore, Xr as imperativeAction, Xt as getDisabledMountTransitionStyles, Yr as focusOut, Yt as usePositioner, Zt as InternalBackdrop, _i as visuallyHiddenInput, _t as strictObject, an as pressableTriggerOpenStateMapping, ar as useOnFirstRender, at as webhookSupportsBody, bi as buttonVariants, bn as useRole, bt as unknown, ci as useLabelableContext, cn as useOpenInteractionType, cr as Timeout, ct as boolean, d as TooltipContent, di as useFieldRootContext, dr as getTabbableAfterElement, dt as json$2, ei as itemPress, en as useDirection, er as fastComponentRef, fi as useBaseUiId, fr as getTabbableBeforeElement, ft as lazy$1, gi as visuallyHidden, gt as record$2, hi as fieldValidityMapping, ht as object$1, ii as siblingOpen, in as popupStateMapping, jn as useImplicitActiveTrigger, jr as ownerDocument, jt as useCompositeListItem, ki as useMergedRefs, kn as popupStoreSelectors, kt as Separator, li as useFormContext, lr as useTimeout, lt as discriminatedUnion, mt as number, ni as none, nn as inertValue, nt as format, oi as triggerHover, on as triggerOpenStateMapping, or as Label, ot as _enum, p as TooltipTrigger, pi as useId$1, pr as isOutsideEvent, pt as literal, qn as POPUP_COLLISION_AVOIDANCE, qr as closePress, qt as useToolbarRootContext, rn as getPseudoElementBounds, rr as createSelector, rt as dequal, sr as Input, st as array, tn as CompositeList, u as Tooltip, ui as useRegisterFieldControl, ur as getNextTabbable, ut as int, vi as useControlled, vn as safePolygon, vt as string$1, wi as useRenderElement, wn as useHoverFloatingInteraction, wt as SelectGroup, xi as cn, xn as useListNavigation, xt as Select, yi as Button, yn as useTypeahead, yt as union, zi as getParentNode, zn as FloatingTree } from "./icons-CajfDpy_.js";
5
5
  import { c as isUiLanguage, d as uiLanguages, i as objectValue, l as resolveUiLanguage, s as valueType, t as initialValue } from "./value-DL_poNiC.js";
6
6
  import "./lib-Dws05GHj.js";
7
7
  import * as React from "react";
@@ -475,7 +475,6 @@ var controlErrorCode = {
475
475
  publicationConflict: "publication.conflict",
476
476
  publicationNotFound: "publication.not-found",
477
477
  publicationUnsupported: "publication.unsupported",
478
- resourceNotFound: "resource.not-found",
479
478
  publishOperationNotFound: "publication.operation-not-found",
480
479
  routeNotFound: "route.not-found",
481
480
  runConflict: "run.conflict",
@@ -492,7 +491,7 @@ var controlErrorCode = {
492
491
  variableLimitReached: "variable.limit-reached",
493
492
  variableNotFound: "variable.not-found"
494
493
  };
495
- controlErrorCode.eventSourceInvalid, controlErrorCode.eventSourceIdentityUnavailable, controlErrorCode.eventSourceNotFound, controlErrorCode.eventSourceConflict, controlErrorCode.authenticationRequired, controlErrorCode.authorizationDenied, controlErrorCode.bindingUnresolved, controlErrorCode.connectorActionNotFound, controlErrorCode.connectorAccessConflict, controlErrorCode.connectorAccessInvalid, controlErrorCode.connectorAccessRequired, controlErrorCode.connectorAccessUnsupported, controlErrorCode.connectorUnconfigured, controlErrorCode.connectorUnavailable, controlErrorCode.connectorConsoleUnconfigured, controlErrorCode.engineUnavailable, controlErrorCode.engineUnsupported, controlErrorCode.flowInvalid, controlErrorCode.flowRepairRequired, controlErrorCode.flowUpgradeRequired, controlErrorCode.flowNotFound, controlErrorCode.flowBusy, controlErrorCode.flowConflict, controlErrorCode.flowPresentationConflict, controlErrorCode.flowRevisionConflict, controlErrorCode.liveConflict, controlErrorCode.liveNotFound, controlErrorCode.pageInvalidCursor, controlErrorCode.publicationConflict, controlErrorCode.publicationNotFound, controlErrorCode.publicationUnsupported, controlErrorCode.resourceNotFound, controlErrorCode.publishOperationNotFound, controlErrorCode.routeNotFound, controlErrorCode.runConflict, controlErrorCode.runEventsExpired, controlErrorCode.runInvalid, controlErrorCode.runNotFound, controlErrorCode.runNotTerminal, controlErrorCode.runOverloaded, controlErrorCode.runWaitNotFound, controlErrorCode.triggerKeyInvalid, controlErrorCode.triggerKeyNotFound, controlErrorCode.triggerNotFound, controlErrorCode.variableInvalid, controlErrorCode.variableLimitReached, controlErrorCode.variableNotFound;
494
+ controlErrorCode.eventSourceInvalid, controlErrorCode.eventSourceIdentityUnavailable, controlErrorCode.eventSourceNotFound, controlErrorCode.eventSourceConflict, controlErrorCode.authenticationRequired, controlErrorCode.authorizationDenied, controlErrorCode.bindingUnresolved, controlErrorCode.connectorActionNotFound, controlErrorCode.connectorAccessConflict, controlErrorCode.connectorAccessInvalid, controlErrorCode.connectorAccessRequired, controlErrorCode.connectorAccessUnsupported, controlErrorCode.connectorUnconfigured, controlErrorCode.connectorUnavailable, controlErrorCode.connectorConsoleUnconfigured, controlErrorCode.engineUnavailable, controlErrorCode.engineUnsupported, controlErrorCode.flowInvalid, controlErrorCode.flowRepairRequired, controlErrorCode.flowUpgradeRequired, controlErrorCode.flowNotFound, controlErrorCode.flowBusy, controlErrorCode.flowConflict, controlErrorCode.flowPresentationConflict, controlErrorCode.flowRevisionConflict, controlErrorCode.liveConflict, controlErrorCode.liveNotFound, controlErrorCode.pageInvalidCursor, controlErrorCode.publicationConflict, controlErrorCode.publicationNotFound, controlErrorCode.publicationUnsupported, controlErrorCode.publishOperationNotFound, controlErrorCode.routeNotFound, controlErrorCode.runConflict, controlErrorCode.runEventsExpired, controlErrorCode.runInvalid, controlErrorCode.runNotFound, controlErrorCode.runNotTerminal, controlErrorCode.runOverloaded, controlErrorCode.runWaitNotFound, controlErrorCode.triggerKeyInvalid, controlErrorCode.triggerKeyNotFound, controlErrorCode.triggerNotFound, controlErrorCode.variableInvalid, controlErrorCode.variableLimitReached, controlErrorCode.variableNotFound;
496
495
  var ApiError = class extends Error {
497
496
  constructor(status, code, message, details) {
498
497
  super(message);
@@ -563,1452 +562,394 @@ function fixedInputValue(value) {
563
562
  };
564
563
  }
565
564
  //#endregion
566
- //#region src/trigger/common/config.ts
567
- function triggerConfigValue(input, config) {
568
- return inputValue(config[input.handle], input.value);
569
- }
570
- /** Provider-specific controls consume values, never persistence wrappers. */
571
- function triggerConfigValues(inputs, config) {
572
- return Object.fromEntries(inputs.flatMap((input) => "handle" in input ? [[input.handle, triggerConfigValue(input, config) ?? null]] : []));
573
- }
574
- //#endregion
575
- //#region src/base/common/json.ts
576
- function hasJsonShape(root) {
577
- if (root === null || typeof root == "boolean" || typeof root == "string") return true;
578
- if (typeof root == "number") return Number.isFinite(root);
579
- if (typeof root != "object") return false;
580
- const ancestors = /* @__PURE__ */ new Set();
581
- const pending = [];
582
- let value = root;
583
- traversal: while (true) {
584
- let keys;
585
- let arrayLength;
586
- if (Array.isArray(value)) {
587
- arrayLength = value.length;
588
- keys = Reflect.ownKeys(value);
589
- if (keys.length != arrayLength + 1) return false;
590
- } else {
591
- const prototype = Reflect.getPrototypeOf(value);
592
- if (prototype != Object.prototype && prototype != null) return false;
593
- keys = Reflect.ownKeys(value);
594
- arrayLength = void 0;
595
- }
596
- ancestors.add(value);
597
- let index = 0;
598
- while (true) {
599
- if (index >= keys.length) {
600
- ancestors.delete(value);
601
- const parent = pending.pop();
602
- if (parent === void 0) return true;
603
- value = parent.value;
604
- keys = parent.keys;
605
- arrayLength = parent.arrayLength;
606
- index = parent.index;
607
- continue;
608
- }
609
- const key = keys[index++];
610
- if (arrayLength !== void 0) {
611
- if (key == "length") continue;
612
- if (typeof key != "string") return false;
613
- const arrayIndex = Number(key);
614
- if (!Number.isSafeInteger(arrayIndex) || arrayIndex < 0 || arrayIndex >= arrayLength || String(arrayIndex) != key) return false;
615
- } else if (typeof key != "string") return false;
616
- const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
617
- if (descriptor?.enumerable != true || !Object.hasOwn(descriptor, "value")) return false;
618
- const child = descriptor.value;
619
- if (child === null || typeof child == "boolean" || typeof child == "string") continue;
620
- if (typeof child == "number") {
621
- if (!Number.isFinite(child)) return false;
622
- continue;
623
- }
624
- if (typeof child != "object" || ancestors.has(child)) return false;
625
- pending.push({
626
- value,
627
- keys,
628
- arrayLength,
629
- index
630
- });
631
- value = child;
632
- continue traversal;
633
- }
634
- }
635
- }
636
- function isJsonObject(value) {
637
- try {
638
- return value != null && typeof value == "object" && !Array.isArray(value) && hasJsonShape(value);
639
- } catch {
640
- return false;
641
- }
642
- }
565
+ //#region src/control/common/authoringLlm.ts
566
+ var authoringLlmConfiguration = strictObject({
567
+ mode: _enum(["chat", "json"]),
568
+ resultSchema: json$2(),
569
+ model: json$2().optional().describe("Default model settings: {model, temperature?, top_p?, max_tokens?}. A bound model input takes precedence."),
570
+ template: json$2().optional().describe("Default message templates: [{role: \"system\" | \"user\" | \"assistant\", content: \"Text with {{namedInput}}\"}]."),
571
+ messages: json$2().optional().describe("Default conversation history, prepended without template interpolation; an array of {role, content} or null.")
572
+ });
643
573
  //#endregion
644
- //#region src/trigger/common/contract.ts
645
- var errorOutputs = [
646
- {
647
- handle: "workflow",
648
- nullable: false,
649
- jsonSchema: {
650
- type: "object",
651
- additionalProperties: false,
652
- required: [
653
- "flowId",
654
- "name",
655
- "revisionId",
656
- "publicationId"
657
- ],
658
- properties: {
659
- flowId: { type: "string" },
660
- name: { type: "string" },
661
- revisionId: { type: "string" },
662
- publicationId: { type: ["string", "null"] }
663
- }
664
- }
665
- },
666
- {
667
- handle: "execution",
668
- nullable: false,
669
- jsonSchema: {
670
- type: "object",
671
- additionalProperties: false,
672
- required: [
673
- "runId",
674
- "status",
675
- "startedAt",
676
- "finishedAt"
677
- ],
678
- properties: {
679
- runId: { type: "string" },
680
- status: { enum: ["failed", "indeterminate"] },
681
- startedAt: { type: ["string", "null"] },
682
- finishedAt: { type: "string" }
683
- }
684
- }
685
- },
686
- {
687
- handle: "error",
688
- nullable: false,
689
- jsonSchema: {
690
- type: "object",
691
- additionalProperties: false,
692
- required: ["code", "message"],
693
- properties: {
694
- code: { type: "string" },
695
- message: { type: "string" },
696
- nodeId: { type: "string" },
697
- jobId: { type: "string" },
698
- path: {
699
- type: "array",
700
- items: { type: "string" }
701
- }
702
- }
703
- }
704
- }
705
- ];
706
- var sampleErrorOutputs = {
707
- workflow: {
708
- flowId: "example-flow",
709
- name: "Example workflow",
710
- revisionId: "example-revision",
711
- publicationId: "example-publication"
712
- },
713
- execution: {
714
- runId: "example-run",
715
- status: "failed",
716
- startedAt: "2026-01-01T00:00:00.000Z",
717
- finishedAt: "2026-01-01T00:00:01.000Z"
718
- },
719
- error: {
720
- code: "node.failed",
721
- message: "Example failure",
722
- nodeId: "example-node",
723
- jobId: "example-job",
724
- path: []
725
- }
726
- };
727
- var webhookOutputs = [
728
- {
729
- handle: "headers",
730
- jsonSchema: {
731
- type: "object",
732
- additionalProperties: { type: "string" }
733
- },
734
- nullable: false
735
- },
736
- {
737
- handle: "query",
738
- jsonSchema: {
739
- type: "object",
740
- additionalProperties: {
741
- type: ["string", "array"],
742
- items: { type: "string" }
743
- }
744
- },
745
- nullable: false
746
- },
747
- {
748
- handle: "body",
749
- jsonSchema: {
750
- type: "object",
751
- additionalProperties: true
752
- },
753
- nullable: false
754
- },
755
- {
756
- handle: "webhookUrl",
757
- jsonSchema: { type: "string" },
758
- nullable: false
759
- }
574
+ //#region src/openapi/common/openapi.ts
575
+ var methods = [
576
+ "get",
577
+ "put",
578
+ "post",
579
+ "delete",
580
+ "options",
581
+ "head",
582
+ "patch",
583
+ "trace"
760
584
  ];
761
- var cronOutputs = [{
762
- handle: "scheduledAt",
763
- jsonSchema: {
764
- type: "string",
765
- format: "date-time"
766
- },
767
- nullable: false
768
- }];
769
- function triggerOutputDefinitions(trigger) {
770
- switch (trigger.kind) {
771
- case "error": return errorOutputs;
772
- case "manual": return [];
773
- case "cron": return cronOutputs;
774
- case "poll":
775
- case "integration": return trigger.definition.outputs;
776
- case "webhook": return webhookOutputs.filter((port) => port.handle !== "body" || webhookSupportsBody(trigger.method)).map((port) => port.handle === "body" ? Object.assign({}, port, { jsonSchema: {
777
- type: "object",
778
- additionalProperties: false,
779
- properties: Object.fromEntries(trigger.bodyFields.map((field) => [field.handle, field.jsonSchema])),
780
- required: trigger.bodyFields.filter((field) => !field.nullable && !Object.hasOwn(field, "value")).map((field) => field.handle)
781
- } }) : port);
782
- }
783
- }
784
- function triggerOutputPorts(trigger) {
785
- return Object.fromEntries(triggerOutputDefinitions(trigger).map(({ handle, ...port }) => [handle, port]));
786
- }
787
- //#endregion
788
- //#region src/flow/common/sourceField.ts
789
- /** Only explicitly declared, first-level object properties are selectable. */
790
- function sourceFields(output) {
791
- const schema = schemaObject(output.jsonSchema);
792
- if (schema == null) return [];
793
- const properties = schemaObject(schema.properties ?? false);
794
- const types = Array.isArray(schema.type) ? schema.type : [schema.type];
795
- if (properties == null || schema.type !== void 0 && !types.includes("object")) return [];
796
- const required = Array.isArray(schema.required) ? schema.required : [];
797
- const missingParent = output.nullable || types.some((type) => type !== "object");
798
- return Object.entries(properties).map(([field, jsonSchema]) => {
799
- const description = schemaObject(jsonSchema)?.description;
800
- return {
801
- field,
802
- port: {
803
- ...typeof description == "string" ? { description } : {},
804
- jsonSchema,
805
- nullable: missingParent || !required.includes(field)
806
- }
807
- };
808
- });
585
+ function object(value) {
586
+ if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error("Expected an OpenAPI object.");
587
+ return value;
809
588
  }
810
- function sourcePort(output, field) {
811
- return field === void 0 ? output : sourceFields(output).find((candidate) => candidate.field === field)?.port;
589
+ function httpUrl(value, base) {
590
+ const url = new URL(value, base);
591
+ if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.hash) throw new Error("An HTTP(S) URL without credentials or fragment is required.");
592
+ return url.href;
812
593
  }
813
- /** Present a selected first-level field as a compact path from its output. */
814
- function sourceOutputLabel(source) {
815
- return source.field === void 0 ? source.output : `${source.output} / ${source.field}`;
594
+ function parseOpenApi(value) {
595
+ const doc = object(value);
596
+ if (typeof doc.openapi != "string" || !/^3\.[01]\.\d+$/.test(doc.openapi)) throw new Error("Only OpenAPI 3.0 and 3.1 JSON documents are supported.");
597
+ object(doc.paths);
598
+ return doc;
816
599
  }
817
- //#endregion
818
- //#region src/flow/common/graph.ts
819
- function isResolutionNode(node) {
820
- return node?.kind == "approval" || node?.kind == "wait";
600
+ function pointer(doc, ref) {
601
+ if (!ref.startsWith("#/")) throw new Error("External OpenAPI references are not supported.");
602
+ let value = doc;
603
+ for (const key of decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"))) {
604
+ const source = object(value);
605
+ if (!Object.hasOwn(source, key)) throw new Error("An OpenAPI reference is missing.");
606
+ value = source[key];
607
+ }
608
+ return value;
821
609
  }
822
- function nodeInputPorts(node) {
823
- switch (node.kind) {
824
- case "condition": return conditionInputPorts(node);
825
- case "value": return {};
826
- case "task": return portsByHandle([...node.task.inputs, ...node.additionalInputs ?? []]);
827
- case "approval":
828
- case "wait": return portsByHandle(node.inputDefinitions);
829
- case "cron":
830
- case "integration":
831
- case "poll":
832
- case "error":
833
- case "manual":
834
- case "webhook": return {};
610
+ function resolved(doc, value) {
611
+ let result = object(value);
612
+ const seen = /* @__PURE__ */ new Set();
613
+ while (typeof result.$ref == "string") {
614
+ if (seen.has(result.$ref)) throw new Error("Circular non-schema reference is unsupported.");
615
+ seen.add(result.$ref);
616
+ const { $ref, ...siblings } = result;
617
+ result = {
618
+ ...object(pointer(doc, $ref)),
619
+ ...siblings
620
+ };
835
621
  }
622
+ return result;
836
623
  }
837
- function resolutionActions(node) {
838
- return node.kind == "wait" ? ["continue"] : ["approve", "reject"];
624
+ function listOperations(documentValue) {
625
+ const doc = parseOpenApi(documentValue);
626
+ return Object.entries(object(doc.paths)).flatMap(([path, value]) => {
627
+ const item = resolved(doc, value);
628
+ return methods.filter((method) => item[method] != null).map((method) => {
629
+ const op = object(item[method]);
630
+ return {
631
+ method,
632
+ path,
633
+ label: String(op.summary ?? op.operationId ?? `${method.toUpperCase()} ${path}`),
634
+ tag: String(op.tags?.[0] ?? "")
635
+ };
636
+ });
637
+ });
839
638
  }
840
- var objectPort = (properties) => ({
841
- nullable: false,
842
- jsonSchema: {
843
- type: "object",
844
- properties,
845
- required: Object.keys(properties),
846
- additionalProperties: false
847
- }
848
- });
849
- function resolutionOutputPorts(node) {
850
- const actions = resolutionActions(node);
851
- const inputs = {
852
- type: "object",
853
- properties: Object.fromEntries(node.inputDefinitions.map((port) => [port.handle, {}])),
854
- required: node.inputDefinitions.map((port) => port.handle),
855
- additionalProperties: false
856
- };
639
+ function operation(doc, path, method) {
640
+ const item = resolved(doc, object(doc.paths)[path]);
641
+ if (!methods.includes(method) || item[method] == null) throw new Error("The selected operation is no longer available.");
857
642
  return {
858
- pending: objectPort({
859
- inputs,
860
- prompt: { type: "string" },
861
- ...Object.fromEntries(actions.map((action) => [`${action}Url`, { type: "string" }])),
862
- expiresAt: { type: "string" }
863
- }),
864
- ...Object.fromEntries(actions.map((action) => [action, objectPort({
865
- inputs,
866
- action: { const: action },
867
- resolvedAt: { type: "string" },
868
- comment: { type: ["string", "null"] }
869
- })]))
643
+ item,
644
+ op: object(item[method])
870
645
  };
871
646
  }
872
- function nodeOutputPorts(node) {
873
- switch (node.kind) {
874
- case "condition": return {};
875
- case "value": return portsByHandle(node.values);
876
- case "task": return portsByHandle(node.task.outputs);
877
- case "approval":
878
- case "wait": return resolutionOutputPorts(node);
879
- case "cron":
880
- case "integration":
881
- case "poll":
882
- case "error":
883
- case "manual":
884
- case "webhook": return triggerOutputPorts(node);
885
- }
647
+ function servers(value, path, method) {
648
+ const doc = parseOpenApi(value);
649
+ const { item, op } = operation(doc, path, method);
650
+ const entries = op.servers ?? item.servers ?? doc.servers;
651
+ if (!Array.isArray(entries) || entries.length == 0) return [{ url: "/" }];
652
+ return entries.map(object);
886
653
  }
887
- function nodeOutputDescription(graph, nodeId, output) {
888
- const node = graph.nodes[nodeId];
889
- return node == null ? void 0 : nodeOutputPorts(node)[output]?.description;
654
+ function serverAddress(server, sourceUrl, variables = {}) {
655
+ return httpUrl(String(server.url).replace(/\{([^}]+)\}/g, (_, name) => {
656
+ const definition = object(object(server.variables)[name]);
657
+ const value = variables[name] ?? definition.default;
658
+ if (typeof value != "string" || Array.isArray(definition.enum) && !definition.enum.includes(value)) throw new Error("A server variable is invalid.");
659
+ return value;
660
+ }), sourceUrl);
890
661
  }
891
- function graphOrder(graph) {
892
- const pending = new Map(Object.keys(graph.nodes).map((id) => [id, /* @__PURE__ */ new Set()]));
893
- const children = /* @__PURE__ */ new Map();
894
- for (const edge of graph.edges) {
895
- if (!pending.has(edge.source) || !pending.has(edge.target)) continue;
896
- pending.get(edge.target)?.add(edge.source);
897
- const targets = children.get(edge.source) ?? /* @__PURE__ */ new Set();
898
- targets.add(edge.target);
899
- children.set(edge.source, targets);
662
+ function securityOptions(value, path, method) {
663
+ const doc = parseOpenApi(value);
664
+ const { op } = operation(doc, path, method);
665
+ const requirements = op.security ?? doc.security ?? [];
666
+ if (!Array.isArray(requirements)) throw new Error("Invalid security requirements.");
667
+ if (!requirements.length) return [{
668
+ label: "None",
669
+ auth: []
670
+ }];
671
+ return requirements.map((entry) => {
672
+ const names = Object.keys(object(entry));
673
+ const label = names.join(" + ") || "None";
674
+ try {
675
+ if (!names.length) return {
676
+ label,
677
+ auth: []
678
+ };
679
+ const schemes = object(object(doc.components).securitySchemes);
680
+ return {
681
+ label,
682
+ auth: names.map((id) => {
683
+ const scheme = resolved(doc, schemes[id]);
684
+ if (scheme.type == "http" && ["bearer", "basic"].includes(String(scheme.scheme).toLowerCase())) return {
685
+ id,
686
+ type: String(scheme.scheme).toLowerCase()
687
+ };
688
+ if (scheme.type == "apiKey" && (scheme.in == "header" || scheme.in == "query") && typeof scheme.name == "string") return {
689
+ id,
690
+ type: "apiKey",
691
+ name: scheme.name,
692
+ in: scheme.in
693
+ };
694
+ throw new Error("This security scheme is unsupported. Supply an access token using manual Bearer authentication if applicable.");
695
+ })
696
+ };
697
+ } catch (error) {
698
+ return {
699
+ label,
700
+ error: error.message
701
+ };
702
+ }
703
+ });
704
+ }
705
+ function snapshot$7(documentValue, path, method) {
706
+ const doc = parseOpenApi(documentValue);
707
+ const { item, op } = operation(doc, path, method);
708
+ const security = op.security ?? doc.security ?? [];
709
+ const result = {
710
+ openapi: doc.openapi,
711
+ paths: { [path]: {
712
+ [method]: op,
713
+ ...item.parameters == null ? {} : { parameters: item.parameters }
714
+ } },
715
+ servers: servers(doc, path, method),
716
+ security
717
+ };
718
+ const visited = /* @__PURE__ */ new Set();
719
+ function copy(ref) {
720
+ if (visited.has(ref)) return;
721
+ visited.add(ref);
722
+ const value = pointer(doc, ref);
723
+ const keys = decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"));
724
+ if (keys.some((key) => [
725
+ "__proto__",
726
+ "constructor",
727
+ "prototype"
728
+ ].includes(key))) throw new Error("Unsupported reference key.");
729
+ let target = result;
730
+ for (const key of keys.slice(0, -1)) {
731
+ if (!Object.hasOwn(target, key)) target[key] = {};
732
+ target = object(target[key]);
733
+ }
734
+ target[keys.at(-1)] = structuredClone(value);
735
+ visit(value);
900
736
  }
901
- const ready = [...pending].filter(([, parents]) => parents.size == 0).map(([id]) => id).toSorted();
902
- for (let index = 0; index < ready.length; index++) {
903
- const id = ready[index];
904
- pending.delete(id);
905
- for (const child of children.get(id) ?? []) {
906
- const parents = pending.get(child);
907
- parents?.delete(id);
908
- if (parents?.size == 0) ready.push(child);
737
+ function visit(value) {
738
+ if (value == null || typeof value != "object") return;
739
+ if (Array.isArray(value)) {
740
+ value.forEach(visit);
741
+ return;
909
742
  }
743
+ if (typeof object(value).$ref == "string") copy(object(value).$ref);
744
+ for (const [key, child] of Object.entries(value)) if (![
745
+ "example",
746
+ "examples",
747
+ "default"
748
+ ].includes(key)) visit(child);
910
749
  }
911
- return [...ready, ...[...pending.keys()].toSorted()];
912
- }
913
- var pathsByGraph = /* @__PURE__ */ new WeakMap();
914
- function routeCovers(route, target) {
915
- return Object.entries(route).every(([key, value]) => target[key] == value);
916
- }
917
- function routesCompatible(left, right) {
918
- return Object.entries(left).every(([key, value]) => right[key] == null || right[key] == value);
919
- }
920
- function resolutionOutputKey(nodeId, output) {
921
- return JSON.stringify([nodeId, output]);
750
+ visit(result);
751
+ for (const entry of security) for (const name of Object.keys(object(entry))) copy(`#/components/securitySchemes/${name.replace(/~/g, "~0").replace(/\//g, "~1")}`);
752
+ return structuredClone(result);
922
753
  }
923
- function graphPaths(graph) {
924
- const cached = pathsByGraph.get(graph);
925
- if (cached != null) return cached;
926
- const paths = /* @__PURE__ */ new Map();
927
- const ancestors = /* @__PURE__ */ new Map();
928
- const resolutionOutputs = /* @__PURE__ */ new Map();
929
- const incoming = /* @__PURE__ */ new Map();
930
- for (const edge of graph.edges) {
931
- const edges = incoming.get(edge.target) ?? [];
932
- edges.push(edge);
933
- incoming.set(edge.target, edges);
934
- }
935
- const order = graphOrder(graph);
936
- let changed = true;
937
- while (changed) {
938
- changed = false;
939
- for (const id of order) {
940
- const node = graph.nodes[id];
941
- const edges = incoming.get(id) ?? [];
942
- const parents = /* @__PURE__ */ new Set();
943
- const resolutions = /* @__PURE__ */ new Set();
944
- const routes = [];
945
- for (const edge of edges) {
946
- parents.add(edge.source);
947
- for (const output of resolutionOutputs.get(edge.source) ?? []) resolutions.add(output);
948
- if (isResolutionNode(graph.nodes[edge.source]) && edge.sourceHandle != null) resolutions.add(resolutionOutputKey(edge.source, edge.sourceHandle));
949
- for (const parent of ancestors.get(edge.source) ?? []) parents.add(parent);
950
- for (const route of paths.get(edge.source) ?? []) {
951
- const next = edge.sourceHandle == null || isResolutionNode(graph.nodes[edge.source]) && edge.sourceHandle == "pending" ? route : {
952
- ...route,
953
- [edge.source]: graph.nodes[edge.source]?.kind == "condition" && graph.nodes[edge.source].matchMode == "all" && edge.sourceHandle != "otherwise" ? "$matched" : edge.sourceHandle
954
- };
955
- if (routes.some((known) => routeCovers(known, next))) continue;
956
- for (let index = routes.length - 1; index >= 0; index--) if (routeCovers(next, routes[index])) routes.splice(index, 1);
957
- routes.push(next);
754
+ function schema$1(doc, schemaValue) {
755
+ const defs = {};
756
+ const ids = /* @__PURE__ */ new Map();
757
+ function convert(value) {
758
+ if (typeof value == "boolean") return value;
759
+ const source = object(value);
760
+ if (source.format == "binary" || source.$dynamicRef != null || source.$id != null) throw new Error("Binary and dynamically scoped schemas are unsupported.");
761
+ const result = {};
762
+ for (const [key, child] of Object.entries(source)) {
763
+ if ([
764
+ "nullable",
765
+ "example",
766
+ "xml",
767
+ "discriminator",
768
+ "__proto__"
769
+ ].includes(key)) continue;
770
+ if (key == "$ref") {
771
+ if (typeof child != "string") throw new Error("Invalid schema reference.");
772
+ let id = ids.get(child);
773
+ if (id == null) {
774
+ id = `s${ids.size}`;
775
+ ids.set(child, id);
776
+ defs[id] = convert(pointer(doc, child));
958
777
  }
778
+ result.$ref = `#/$defs/${id}`;
779
+ } else if ([
780
+ "properties",
781
+ "patternProperties",
782
+ "$defs",
783
+ "definitions",
784
+ "dependentSchemas"
785
+ ].includes(key)) result[key] = Object.fromEntries(Object.entries(object(child)).map(([name, childSchema]) => [name, convert(childSchema)]));
786
+ else if ([
787
+ "allOf",
788
+ "anyOf",
789
+ "oneOf",
790
+ "prefixItems"
791
+ ].includes(key)) {
792
+ if (!Array.isArray(child)) throw new Error("Invalid schema composition.");
793
+ result[key] = child.map(convert);
794
+ } else if ([
795
+ "items",
796
+ "additionalProperties",
797
+ "not",
798
+ "if",
799
+ "then",
800
+ "else",
801
+ "contains",
802
+ "propertyNames",
803
+ "unevaluatedProperties"
804
+ ].includes(key)) result[key] = convert(child);
805
+ else result[key] = child;
806
+ }
807
+ if (source.nullable === true) return { anyOf: [result, { type: "null" }] };
808
+ for (const key of ["minimum", "maximum"]) {
809
+ const exclusive = key == "minimum" ? "exclusiveMinimum" : "exclusiveMaximum";
810
+ if (typeof result[exclusive] == "boolean") {
811
+ if (result[exclusive] && typeof result[key] == "number") {
812
+ result[exclusive] = result[key];
813
+ delete result[key];
814
+ } else delete result[exclusive];
959
815
  }
960
- const nextRoutes = edges.length == 0 ? "inputs" in node ? [{}] : [{ $trigger: id }] : routes;
961
- const previous = paths.get(id) ?? [];
962
- if (parents.size != (ancestors.get(id)?.size ?? 0) || resolutions.size != (resolutionOutputs.get(id)?.size ?? 0) || nextRoutes.length != previous.length || nextRoutes.some((route) => !previous.some((known) => routeCovers(known, route) && routeCovers(route, known)))) changed = true;
963
- ancestors.set(id, parents);
964
- resolutionOutputs.set(id, resolutions);
965
- paths.set(id, nextRoutes);
966
816
  }
817
+ return result;
967
818
  }
968
- const analysis = {
969
- ancestors,
970
- paths,
971
- resolutionOutputs
819
+ let converted = convert(schemaValue);
820
+ if (typeof converted == "object" && converted != null && typeof object(converted).$ref == "string") {
821
+ const id = String(object(converted).$ref).slice(8);
822
+ const { $ref: _ref, ...siblings } = object(converted);
823
+ converted = {
824
+ ...object(defs[id]),
825
+ ...siblings
826
+ };
827
+ }
828
+ if (typeof converted == "boolean") return converted;
829
+ return {
830
+ $schema: "https://json-schema.org/draft/2020-12/schema",
831
+ ...object(converted),
832
+ ...Object.keys(defs).length ? { $defs: defs } : {}
972
833
  };
973
- pathsByGraph.set(graph, analysis);
974
- return analysis;
975
- }
976
- function sourcePaths(graph, paths, source) {
977
- if (source.kind != "node") return [{}];
978
- const node = graph.nodes[source.nodeId];
979
- const routes = paths.get(source.nodeId) ?? [];
980
- return node?.kind == "condition" || isResolutionNode(node) && source.output != "pending" ? routes.map((route) => ({
981
- ...route,
982
- [source.nodeId]: source.output
983
- })) : routes;
984
834
  }
985
- function mappingAvailable(graph, target, mapping, analysis) {
986
- if (mapping.kind != "sources") return true;
987
- const { ancestors, paths } = analysis;
988
- if (target != null && mapping.sources.some((source) => source.kind == "node" && !ancestors.get(target)?.has(source.nodeId))) return false;
989
- if (target != null && mapping.sources.some((source) => source.kind == "node" && isResolutionNode(graph.nodes[source.nodeId]) && !analysis.resolutionOutputs.get(target)?.has(resolutionOutputKey(source.nodeId, source.output)))) return false;
990
- const sources = mapping.sources.map((source) => sourcePaths(graph, paths, source));
991
- const targetPaths = target == null ? [{}] : paths.get(target) ?? [];
992
- for (const [index, routes] of sources.entries()) for (const [offset, other] of sources.slice(index + 1).entries()) {
993
- const leftSource = mapping.sources[index];
994
- const rightSource = mapping.sources[index + offset + 1];
995
- if (target != null && leftSource.kind == "node" && rightSource.kind == "node" && leftSource.nodeId != rightSource.nodeId && !ancestors.get(leftSource.nodeId)?.has(rightSource.nodeId) && !ancestors.get(rightSource.nodeId)?.has(leftSource.nodeId)) continue;
996
- for (const left of routes) for (const targetRoute of targetPaths) {
997
- if (!routesCompatible(left, targetRoute)) continue;
998
- const path = {
999
- ...targetRoute,
1000
- ...left
1001
- };
1002
- if (other.some((right) => routesCompatible(right, path))) return false;
1003
- }
835
+ function parameters(config) {
836
+ const doc = parseOpenApi(config.document);
837
+ const { item, op } = operation(doc, config.path, config.method);
838
+ const entries = /* @__PURE__ */ new Map();
839
+ for (const value of [...item.parameters ?? [], ...op.parameters ?? []]) {
840
+ const p = resolved(doc, value);
841
+ if (![
842
+ "path",
843
+ "query",
844
+ "header"
845
+ ].includes(String(p.in)) || typeof p.name != "string" || p.content != null) throw new Error("Only schema-based path, query and header parameters are supported.");
846
+ if (p.allowReserved === true) throw new Error("allowReserved parameters are unsupported.");
847
+ if ((p.style ?? (p.in == "query" ? "form" : "simple")) != (p.in == "query" ? "form" : "simple")) throw new Error("Only form query and simple path/header serialization are supported.");
848
+ entries.set(`${p.in}.${p.in == "header" ? p.name.toLowerCase() : p.name}`, p);
1004
849
  }
1005
- return true;
1006
- }
1007
- function sourceCompatibility(source, input) {
1008
- const result = comparePorts(source, input);
1009
- if (result.kind == "compatible") return { kind: "available" };
1010
- return result.kind == "incompatible" ? {
1011
- kind: "schema",
1012
- mismatch: result.mismatch
1013
- } : { kind: "schema-error" };
1014
- }
1015
- /** Check one saved binding without enumerating candidate ports. */
1016
- function checkInputSource(graph, target, handle, source) {
1017
- const node = graph.nodes[source.nodeId];
1018
- const targetNode = graph.nodes[target];
1019
- if (node == null) return { kind: "source-missing" };
1020
- if (targetNode == null) return { kind: "not-ready" };
1021
- const output = nodeOutputPorts(node)[source.output];
1022
- const input = nodeInputPorts(targetNode)[handle];
1023
- if (output == null) return { kind: "output-missing" };
1024
- if (input == null) return { kind: "not-ready" };
1025
- const analysis = graphPaths(graph);
1026
- if (analysis.ancestors.get(target)?.has(source.nodeId) !== true) return { kind: "not-ready" };
1027
- if (isResolutionNode(node) && !analysis.resolutionOutputs.get(target)?.has(resolutionOutputKey(source.nodeId, source.output))) return { kind: "not-ready" };
1028
- const selected = sourcePort(output, source.field);
1029
- if (selected == null) return { kind: "field-missing" };
1030
- return sourceCompatibility(selected, input);
850
+ return [...entries.values()];
1031
851
  }
1032
- function checkInputSources(graph, target, handle, sources) {
1033
- const checks = sources.map((source) => checkInputSource(graph, target, handle, source));
852
+ function jsonContent(doc, value) {
853
+ const content = resolved(doc, value);
854
+ const media = object(content.content);
855
+ const mediaType = media["application/json"] != null ? "application/json" : Object.keys(media).find((key) => /^application\/.+\+json$/.test(key));
856
+ const json = mediaType == null ? void 0 : media[mediaType];
857
+ if (json == null) throw new Error("Only JSON request and response bodies are supported.");
1034
858
  return {
1035
- conflict: checks.length > 1 && checks.every((check) => check.kind == "available") && !mappingAvailable(graph, target, {
1036
- kind: "sources",
1037
- sources: sources.map((source) => ({
1038
- kind: "node",
1039
- ...source
1040
- }))
1041
- }, graphPaths(graph)),
1042
- sources: checks
859
+ schema: schema$1(doc, object(json).schema ?? {}),
860
+ required: content.required === true,
861
+ mediaType
1043
862
  };
1044
863
  }
1045
- /** Enumerate structurally available outputs while retaining their compatibility with one input. */
1046
- function inputSourceCandidates(graph, target, handle) {
1047
- const targetNode = graph.nodes[target];
1048
- const input = targetNode == null ? void 0 : nodeInputPorts(targetNode)[handle];
1049
- if (input == null) return {};
1050
- const analysis = graphPaths(graph);
1051
- return Object.fromEntries([...analysis.ancestors.get(target) ?? []].flatMap((nodeId) => {
1052
- const node = graph.nodes[nodeId];
1053
- if (node == null) return [];
1054
- const outputs = Object.entries(nodeOutputPorts(node)).flatMap(([output, definition]) => {
1055
- if (!mappingAvailable(graph, target, {
1056
- kind: "sources",
1057
- sources: [{
1058
- kind: "node",
1059
- nodeId,
1060
- output
1061
- }]
1062
- }, analysis)) return [];
1063
- const check = sourceCompatibility(definition, input);
1064
- const fields = sourceFields(definition).map(({ field, port }) => Object.assign({
1065
- output,
1066
- field,
1067
- check: sourceCompatibility(port, input)
1068
- }, port.description == null ? {} : { description: port.description }));
1069
- return [{
1070
- ...definition.description == null ? {} : { description: definition.description },
1071
- output,
1072
- check,
1073
- ...fields.length > 0 ? { fields } : {}
1074
- }];
1075
- });
1076
- return outputs.length == 0 ? [] : [[nodeId, outputs]];
1077
- }));
864
+ function authHandles(auth) {
865
+ return auth.flatMap((scheme) => scheme.type == "basic" ? [`auth.${scheme.id}.username`, `auth.${scheme.id}.password`] : [`auth.${scheme.id}.token`]);
1078
866
  }
1079
- //#endregion
1080
- //#region src/flow/common/moduleChanges.ts
1081
- async function imports(source) {
1082
- try {
1083
- const { parse } = await import("./lib-Dws05GHj.js").then((n) => n.t);
1084
- const program = parse(source, {
1085
- errorRecovery: true,
1086
- sourceType: "module"
1087
- }).program;
1088
- const dependencies = /* @__PURE__ */ new Set();
1089
- for (const statement of program.body) {
1090
- if (statement.type != "ImportDeclaration") continue;
1091
- const match = /^\.\/(.+)\.mjs$/.exec(statement.source.value);
1092
- if (match?.[1] != null) dependencies.add(match[1]);
1093
- }
1094
- return [...dependencies].toSorted();
1095
- } catch {
1096
- return [];
867
+ function openApiTask(config, name = "OpenAPI") {
868
+ if (!config.path) return {
869
+ name,
870
+ executor: config,
871
+ inputs: [],
872
+ outputs: []
873
+ };
874
+ const doc = parseOpenApi(config.document);
875
+ const { op } = operation(doc, config.path, config.method);
876
+ const params = parameters(config);
877
+ const inputs = params.map((p) => {
878
+ const jsonSchema = schema$1(doc, p.schema ?? {});
879
+ const defaultValue = typeof jsonSchema == "boolean" ? void 0 : object(jsonSchema).default;
880
+ return {
881
+ handle: `${p.in}.${p.name}`,
882
+ jsonSchema,
883
+ nullable: p.required !== true && p.in != "path" || matchesSchema(null, jsonSchema),
884
+ ...typeof p.description == "string" ? { description: p.description } : {},
885
+ ...defaultValue === void 0 ? {} : { value: defaultValue }
886
+ };
887
+ });
888
+ if (op.requestBody != null) {
889
+ if (config.method == "get" || config.method == "head") throw new Error("GET and HEAD request bodies are unsupported.");
890
+ const body = jsonContent(doc, op.requestBody);
891
+ inputs.push({
892
+ handle: "body",
893
+ jsonSchema: body.schema,
894
+ nullable: !body.required || matchesSchema(null, body.schema)
895
+ });
1097
896
  }
1098
- }
1099
- function replaceSource(moduleId, beforeSource, beforeImports, source, moduleImports) {
1100
- return [{
1101
- beforeImports,
1102
- beforeSource,
1103
- imports: moduleImports,
1104
- kind: "module.source.replace",
1105
- moduleId,
1106
- source
1107
- }];
1108
- }
1109
- //#endregion
1110
- //#region src/flow/common/nodeChanges.ts
1111
- var codeTaskTemplate = `export default async function (inputs, context) {
1112
- return { result: inputs.value }
1113
- }
1114
- `;
1115
- var defaultCodeTaskPorts = {
1116
- inputs: [{
1117
- handle: "value",
1118
- jsonSchema: { type: "string" },
1119
- nullable: true,
1120
- value: "foo"
1121
- }],
1122
- outputs: [{
1123
- handle: "result",
1124
- jsonSchema: {},
1125
- nullable: true
1126
- }]
1127
- };
1128
- function defaultNodeName(_content, node) {
1129
- switch (node.kind) {
1130
- case "condition": return "Condition";
1131
- case "value": return "Fixed Values";
1132
- case "approval": return "Approval";
1133
- case "wait": return "Wait";
1134
- case "task": return normalizeNodeName(node.task.name) || "Task";
1135
- case "error": return "Flow Error";
1136
- case "manual": return "Manual Trigger";
1137
- case "webhook": return "Webhook";
1138
- case "cron": return "Scheduled Trigger";
1139
- case "integration":
1140
- case "poll": return normalizeNodeName(node.definition.displayName) || "Trigger";
897
+ const occupied = new Set(params.map((p) => `${p.in}.${p.in == "header" ? String(p.name).toLowerCase() : p.name}`));
898
+ for (const auth of config.auth) {
899
+ const location = auth.type == "apiKey" ? `${auth.in}.${auth.in == "header" ? auth.name?.toLowerCase() : auth.name}` : "header.authorization";
900
+ if (occupied.has(location)) throw new Error("Authentication conflicts with a parameter or another security scheme.");
901
+ if (auth.type == "apiKey" && (!auth.name || !["header", "query"].includes(auth.in ?? ""))) throw new Error("API Key requires a name and location.");
902
+ occupied.add(location);
1141
903
  }
1142
- }
1143
- function graphNameRepairs(content, targetGraph) {
1144
- const names = /* @__PURE__ */ new Set();
1145
- const changed = [];
1146
- for (const [nodeId, node] of Object.entries(targetGraph.nodes)) {
1147
- const requested = normalizeNodeName(node.name ?? "") || defaultNodeName(content, node);
1148
- const name = nextNodeName(requested, names);
1149
- names.add(name);
1150
- if (node.name != name) changed.push({
1151
- name,
1152
- node,
1153
- nodeId
1154
- });
904
+ inputs.push(...authHandles(config.auth).map((handle) => ({
905
+ handle,
906
+ jsonSchema: { type: "string" },
907
+ nullable: false
908
+ })));
909
+ const responses = object(op.responses);
910
+ const schemas = [];
911
+ for (const [status, response] of Object.entries(responses)) if (/^2\d\d$|^2XX$/.test(status) || status == "default") {
912
+ const r = resolved(doc, response);
913
+ if (r.content == null) schemas.push({ type: "null" });
914
+ else {
915
+ jsonContent(doc, r);
916
+ for (const [mediaType, media] of Object.entries(object(r.content))) if (/^application\/(json|.+\+json)$/.test(mediaType)) schemas.push(schema$1(doc, object(media).schema ?? {}));
917
+ }
1155
918
  }
1156
- return changed.toReversed().map(({ name, node, nodeId }) => ({
1157
- before: node.name,
1158
- field: "name",
1159
- kind: "graph.node.field.set",
1160
- nodeId,
1161
- value: name
1162
- }));
1163
- }
1164
- function repairNodeNames(content) {
1165
- return graphNameRepairs(content, content.document.graph);
1166
- }
1167
- function createCodeTask(identity, name, module = void 0, ports = defaultCodeTaskPorts) {
1168
- return [{
1169
- kind: "module.create",
1170
- module: {
1171
- ...module ?? {
1172
- imports: [],
1173
- source: codeTaskTemplate
1174
- },
1175
- name
1176
- },
1177
- moduleId: identity.moduleId
1178
- }, {
1179
- kind: "graph.node.create",
1180
- node: {
1181
- inputs: defaultInputs(ports.inputs),
1182
- kind: "task",
1183
- name,
1184
- task: {
1185
- capabilities: ports.capabilities ?? [{
1186
- kind: "connector",
1187
- mode: "independent",
1188
- actions: []
1189
- }],
1190
- inputs: ports.inputs,
1191
- moduleId: identity.moduleId,
1192
- name,
1193
- outputs: ports.outputs
1194
- }
1195
- },
1196
- nodeId: identity.nodeId
1197
- }];
1198
- }
1199
- function createManagedTask(identity, task) {
1200
- return [{
1201
- kind: "graph.node.create",
1202
- node: {
1203
- inputs: defaultInputs(task.inputs),
1204
- kind: "task",
1205
- name: task.name,
1206
- task
1207
- },
1208
- nodeId: identity.nodeId
1209
- }];
1210
- }
1211
- function createAgentTask(identity, name, defaults = {}) {
1212
- return createManagedTask(identity, {
919
+ if (!schemas.length) throw new Error("A successful JSON response definition is required.");
920
+ return {
1213
921
  name,
1214
- inputs: defaults.inputs ?? [{
1215
- handle: "input",
1216
- jsonSchema: { type: "string" },
1217
- nullable: false,
1218
- value: ""
1219
- }],
1220
- outputs: [{
1221
- handle: "output",
1222
- jsonSchema: { type: "string" },
1223
- nullable: false,
1224
- description: defaults.outputDescription ?? "The final result produced by the Agent."
1225
- }],
1226
- executor: {
1227
- kind: "agent",
1228
- model: "deepseek-v4-flash",
1229
- prompt: defaults.prompt ?? "Summarize the following content, highlighting key points and next steps.\n\n{{input}}",
1230
- maxRounds: 10,
1231
- tools: []
1232
- }
1233
- });
1234
- }
1235
- function createLlmTask(identity, name, mode, outputDescription, options = {}) {
1236
- const values = options.inputs ?? {};
1237
- return createManagedTask(identity, {
1238
- executor: {
1239
- kind: "llm",
1240
- mode
1241
- },
1242
- inputs: [
922
+ executor: config,
923
+ inputs,
924
+ outputs: [
1243
925
  {
1244
- handle: "messages",
1245
- jsonSchema: {
1246
- items: { type: "object" },
1247
- type: "array"
926
+ handle: "body",
927
+ jsonSchema: schemas.length == 1 ? schemas[0] : {
928
+ $schema: "https://json-schema.org/draft/2020-12/schema",
929
+ anyOf: schemas.map((s, index) => inlineSchema(s, index))
1248
930
  },
1249
- nullable: true,
1250
- value: llmInputValue(values, "messages", null)
931
+ nullable: config.method == "head" || schemas.some((item) => matchesSchema(null, item))
1251
932
  },
1252
933
  {
1253
- handle: "input",
1254
- jsonSchema: { type: "string" },
1255
- nullable: false,
1256
- value: llmInputValue(values, "input", "Alex")
934
+ handle: "statusCode",
935
+ jsonSchema: { type: "integer" },
936
+ nullable: false
1257
937
  },
1258
938
  {
1259
- handle: "template",
939
+ handle: "headers",
1260
940
  jsonSchema: {
1261
- items: { type: "object" },
1262
- minItems: 1,
1263
- type: "array"
941
+ type: "object",
942
+ additionalProperties: { type: "string" }
1264
943
  },
1265
- nullable: false,
1266
- value: llmInputValue(values, "template", [{
1267
- content: "Hello, I'm {{input}}",
1268
- role: "user"
1269
- }])
1270
- },
1271
- {
1272
- handle: "model",
1273
- jsonSchema: { type: "object" },
1274
- nullable: false,
1275
- value: llmInputValue(values, "model", { model: "deepseek-v4-flash" })
944
+ nullable: false
1276
945
  }
1277
- ],
1278
- name,
1279
- outputs: [{
1280
- ...options.output,
1281
- description: options.output?.description ?? outputDescription,
1282
- handle: "output",
1283
- jsonSchema: options.output?.jsonSchema ?? (mode == "chat" ? { type: "string" } : {}),
1284
- nullable: options.output?.nullable ?? false
1285
- }]
1286
- });
946
+ ]
947
+ };
1287
948
  }
1288
- function createCondition(nodeId, name) {
1289
- return [{
1290
- kind: "graph.node.create",
1291
- node: {
1292
- cases: [{
1293
- groups: [{ expressions: [{
1294
- left: { kind: "value" },
1295
- operator: "==",
1296
- right: { kind: "value" }
1297
- }] }],
1298
- output: "case"
1299
- }],
1300
- matchMode: "first",
1301
- inputs: {},
1302
- kind: "condition",
1303
- name
1304
- },
1305
- nodeId
1306
- }];
1307
- }
1308
- function createValue(nodeId, name, values = [{
1309
- handle: "value",
1310
- jsonSchema: {},
1311
- nullable: true,
1312
- value: null
1313
- }]) {
1314
- return [{
1315
- kind: "graph.node.create",
1316
- node: {
1317
- inputs: {},
1318
- kind: "value",
1319
- name,
1320
- values
1321
- },
1322
- nodeId
1323
- }];
1324
- }
1325
- function createWait(nodeId, name) {
1326
- return [{
1327
- kind: "graph.node.create",
1328
- node: {
1329
- inputDefinitions: [],
1330
- inputs: {},
1331
- kind: "wait",
1332
- name,
1333
- prompt: name
1334
- },
1335
- nodeId
1336
- }];
1337
- }
1338
- function createApproval(nodeId, name) {
1339
- return [{
1340
- kind: "graph.node.create",
1341
- node: {
1342
- inputDefinitions: [],
1343
- inputs: {},
1344
- kind: "approval",
1345
- name,
1346
- prompt: name
1347
- },
1348
- nodeId
1349
- }];
1350
- }
1351
- function createBuiltinTrigger(nodeId, node) {
1352
- return [{
1353
- kind: "graph.node.create",
1354
- node,
1355
- nodeId
1356
- }];
1357
- }
1358
- function createProviderTrigger(nodeId, definition, options) {
1359
- const name = options.name ?? definition.displayName;
1360
- return [{
1361
- kind: "graph.node.create",
1362
- node: definition.type == "poll" ? {
1363
- ...options.connectionId == null ? {} : { connectionId: options.connectionId },
1364
- config: inputValues(options.config),
1365
- definition,
1366
- kind: "poll",
1367
- name,
1368
- pollTimes: options.schedule ?? [{
1369
- type: "every",
1370
- unit: "minute",
1371
- value: 5
1372
- }]
1373
- } : {
1374
- ...options.connectionId == null ? {} : { connectionId: options.connectionId },
1375
- config: inputValues(options.config),
1376
- definition,
1377
- kind: "integration",
1378
- name
1379
- },
1380
- nodeId
1381
- }];
1382
- }
1383
- function deleteNodes(content, nodeIds) {
1384
- const nodes = content.document.graph?.nodes;
1385
- if (nodes == null) return [];
1386
- return cleanVariableBindings(content, nodeIds.flatMap((nodeId) => {
1387
- const node = nodes[nodeId];
1388
- if (node == null) return [];
1389
- return [{
1390
- kind: "graph.node.delete",
1391
- nodeId
1392
- }, ...node.kind == "task" && "moduleId" in node.task ? [{
1393
- kind: "module.delete",
1394
- moduleId: node.task.moduleId
1395
- }] : []];
1396
- }));
1397
- }
1398
- function updateSettings(content, nodeId, settings) {
1399
- const node = content.document.graph?.nodes[nodeId];
1400
- if (node == null || !("inputs" in node)) return;
1401
- const operations = [];
1402
- if (node.name != settings.name) operations.push({
1403
- before: node.name,
1404
- field: "name",
1405
- kind: "graph.node.field.set",
1406
- nodeId,
1407
- value: settings.name
1408
- });
1409
- if (node.maxExecutions != settings.maxExecutions) operations.push({
1410
- before: node.maxExecutions,
1411
- field: "maxExecutions",
1412
- kind: "graph.node.field.set",
1413
- nodeId,
1414
- value: settings.maxExecutions
1415
- });
1416
- if (node.timeoutMs != settings.timeoutMs) operations.push({
1417
- before: node.timeoutMs,
1418
- field: "timeoutMs",
1419
- kind: "graph.node.field.set",
1420
- nodeId,
1421
- value: settings.timeoutMs
1422
- });
1423
- return operations;
1424
- }
1425
- function setInputValue$1(content, nodeId, handle, value) {
1426
- return setInputValues(content, nodeId, { [handle]: value });
1427
- }
1428
- function setInputValues(content, nodeId, values) {
1429
- const node = content.document.graph?.nodes[nodeId];
1430
- if (node == null || !("inputs" in node)) return;
1431
- const operations = [];
1432
- for (const [handle, value] of Object.entries(values)) {
1433
- const before = nodeInputMappings(node)[handle];
1434
- const next = fixedInputValue(value);
1435
- if (dequal(before, next)) continue;
1436
- operations.push({
1437
- before,
1438
- handle,
1439
- kind: "graph.node.input.set",
1440
- nodeId,
1441
- value: next
1442
- });
1443
- }
1444
- return cleanVariableBindings(content, operations);
1445
- }
1446
- /** Restore inheritance for this form in one undoable change. */
1447
- function resetInputValues(content, nodeId, handles) {
1448
- const node = content.document.graph?.nodes[nodeId];
1449
- if (node == null || !("inputs" in node)) return [];
1450
- const mappings = nodeInputMappings(node);
1451
- return cleanVariableBindings(content, [...new Set(handles)].flatMap((handle) => mappings[handle] == null ? [] : [{
1452
- kind: "graph.node.input.set",
1453
- nodeId,
1454
- handle,
1455
- before: mappings[handle],
1456
- value: void 0
1457
- }]));
1458
- }
1459
- function setInputSources(content, nodeId, handle, sources) {
1460
- const node = content.document.graph?.nodes[nodeId];
1461
- if (node == null || !("inputs" in node)) return [];
1462
- return cleanVariableBindings(content, [{
1463
- kind: "graph.node.input.set",
1464
- nodeId,
1465
- handle,
1466
- before: nodeInputMappings(node)[handle],
1467
- value: {
1468
- kind: "sources",
1469
- sources
1470
- }
1471
- }]);
1472
- }
1473
- function setInputVariable$1(content, nodeId, handle, name, bindingId) {
1474
- const node = content.document.graph?.nodes[nodeId];
1475
- if (node == null || !("inputs" in node)) return;
1476
- const mapping = nodeInputMappings(node)[handle];
1477
- const currentId = mapping?.kind == "sources" && mapping.sources.length == 1 && mapping.sources[0]?.kind == "binding" ? mapping.sources[0].bindingId : void 0;
1478
- const current = currentId == null ? void 0 : content.document.bindings[currentId];
1479
- const references = bindingReferences(content.document);
1480
- if (currentId != null && current?.kind == "variable" && (references.get(currentId) ?? 0) == 1) {
1481
- if (current.target == name) return [];
1482
- return [{
1483
- before: current.target,
1484
- bindingId: currentId,
1485
- kind: "binding.target.set",
1486
- value: name
1487
- }];
1488
- }
1489
- return [{
1490
- binding: {
1491
- kind: "variable",
1492
- target: name
1493
- },
1494
- bindingId,
1495
- kind: "binding.create"
1496
- }, ...cleanVariableBindings(content, [{
1497
- before: mapping,
1498
- handle,
1499
- kind: "graph.node.input.set",
1500
- nodeId,
1501
- value: {
1502
- kind: "sources",
1503
- sources: [{
1504
- bindingId,
1505
- kind: "binding"
1506
- }]
1507
- }
1508
- }])];
1509
- }
1510
- function cleanVariableBindings(content, operations) {
1511
- const before = bindingReferences(content.document);
1512
- const changed = applyFlowChanges$1(content, operations);
1513
- const after = bindingReferences(changed.document);
1514
- return [...operations, ...[...before.keys()].flatMap((bindingId) => after.has(bindingId) || changed.document.bindings[bindingId]?.kind != "variable" ? [] : [{
1515
- bindingId,
1516
- kind: "binding.delete"
1517
- }])];
1518
- }
1519
- function bindingReferences(document) {
1520
- const references = /* @__PURE__ */ new Map();
1521
- const add = (bindingId) => {
1522
- references.set(bindingId, (references.get(bindingId) ?? 0) + 1);
1523
- };
1524
- for (const node of Object.values(document.graph.nodes)) {
1525
- if (!("inputs" in node)) continue;
1526
- const inputs = Object.values(nodeInputMappings(node));
1527
- for (const mapping of inputs) {
1528
- if (mapping.kind != "sources") continue;
1529
- for (const source of mapping.sources) if (source.kind == "binding") add(source.bindingId);
1530
- }
1531
- }
1532
- return references;
1533
- }
1534
- function setConnectorConnection(content, nodeId, connectionId) {
1535
- const node = content.document.graph.nodes[nodeId];
1536
- if (node?.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "connector") return;
1537
- const task = node.task;
1538
- if (task.executor.kind != "connector") return;
1539
- if (task.executor.connectionId == connectionId) return [];
1540
- const { connectionId: _, ...executor } = task.executor;
1541
- return [{
1542
- before: task,
1543
- kind: "graph.node.task.set",
1544
- nodeId,
1545
- value: {
1546
- ...task,
1547
- executor: {
1548
- ...executor,
1549
- ...connectionId == null ? {} : { connectionId }
1550
- }
1551
- }
1552
- }];
1553
- }
1554
- function updateTriggerConfig(content, nodeId, name, value) {
1555
- const trigger = content.document.graph.nodes[nodeId];
1556
- if (trigger == null || trigger.kind != "integration" && trigger.kind != "poll") return;
1557
- const next = fixedInputValue(value);
1558
- if (dequal(trigger.config[name], next)) return [];
1559
- return [{
1560
- before: trigger.config[name],
1561
- kind: "graph.trigger.config.set",
1562
- name,
1563
- nodeId,
1564
- value: next
1565
- }];
1566
- }
1567
- function updateTriggerSchedule(content, nodeId, schedule) {
1568
- const trigger = content.document.graph.nodes[nodeId];
1569
- if (trigger == null) return;
1570
- switch (trigger.kind) {
1571
- case "cron": return dequal(trigger.cronTimes, schedule) ? [] : [{
1572
- before: trigger.cronTimes,
1573
- kind: "graph.trigger.schedule.set",
1574
- nodeId,
1575
- value: schedule
1576
- }];
1577
- case "poll": return dequal(trigger.pollTimes, schedule) ? [] : [{
1578
- before: trigger.pollTimes,
1579
- kind: "graph.trigger.schedule.set",
1580
- nodeId,
1581
- value: schedule
1582
- }];
1583
- case "integration":
1584
- case "manual":
1585
- case "webhook": return;
1586
- default: return;
1587
- }
1588
- }
1589
- function setTriggerConnection(content, nodeId, connectionId) {
1590
- const trigger = content.document.graph.nodes[nodeId];
1591
- if (trigger == null || trigger.kind != "poll" && trigger.kind != "integration") return;
1592
- if (trigger.connectionId == connectionId) return [];
1593
- return [{
1594
- before: trigger.connectionId,
1595
- kind: "graph.node.field.set",
1596
- field: "connectionId",
1597
- nodeId,
1598
- value: connectionId
1599
- }];
1600
- }
1601
- function defaultInputs(ports) {
1602
- return Object.fromEntries(ports.flatMap((port) => "handle" in port && Object.hasOwn(port, "value") ? [[port.handle, {
1603
- kind: "value",
1604
- value: port.value
1605
- }]] : []));
1606
- }
1607
- function llmInputValue(values, handle, fallback) {
1608
- return values != null && Object.hasOwn(values, handle) ? values[handle] : fallback;
1609
- }
1610
- function setCodeActions(content, nodeId, capabilities) {
1611
- const node = content.document.graph?.nodes[nodeId];
1612
- if (node?.kind != "task" || !("moduleId" in node.task) || dequal(node.task.capabilities ?? [], capabilities)) return;
1613
- return [{
1614
- kind: "graph.node.task.capabilities.set",
1615
- nodeId,
1616
- before: node.task.capabilities,
1617
- value: capabilities
1618
- }];
1619
- }
1620
- function createDecisionTask(identity, name = "AI Decision", questions) {
1621
- return createManagedTask(identity, decisionTask(questions, name));
1622
- }
1623
- //#endregion
1624
- //#region src/control/common/authoringLlm.ts
1625
- var authoringLlmConfiguration = strictObject({
1626
- mode: _enum(["chat", "json"]),
1627
- resultSchema: json$2(),
1628
- model: json$2().optional().describe("Default model settings: {model, temperature?, top_p?, max_tokens?}. A bound model input takes precedence."),
1629
- template: json$2().optional().describe("Default message templates: [{role: \"system\" | \"user\" | \"assistant\", content: \"Text with {{namedInput}}\"}]."),
1630
- messages: json$2().optional().describe("Default conversation history, prepended without template interpolation; an array of {role, content} or null.")
1631
- });
1632
- //#endregion
1633
- //#region src/openapi/common/openapi.ts
1634
- var methods = [
1635
- "get",
1636
- "put",
1637
- "post",
1638
- "delete",
1639
- "options",
1640
- "head",
1641
- "patch",
1642
- "trace"
1643
- ];
1644
- function object(value) {
1645
- if (value == null || typeof value != "object" || Array.isArray(value)) throw new Error("Expected an OpenAPI object.");
1646
- return value;
1647
- }
1648
- function httpUrl(value, base) {
1649
- const url = new URL(value, base);
1650
- if (!["http:", "https:"].includes(url.protocol) || url.username || url.password || url.hash) throw new Error("An HTTP(S) URL without credentials or fragment is required.");
1651
- return url.href;
1652
- }
1653
- function parseOpenApi(value) {
1654
- const doc = object(value);
1655
- if (typeof doc.openapi != "string" || !/^3\.[01]\.\d+$/.test(doc.openapi)) throw new Error("Only OpenAPI 3.0 and 3.1 JSON documents are supported.");
1656
- object(doc.paths);
1657
- return doc;
1658
- }
1659
- function pointer(doc, ref) {
1660
- if (!ref.startsWith("#/")) throw new Error("External OpenAPI references are not supported.");
1661
- let value = doc;
1662
- for (const key of decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"))) {
1663
- const source = object(value);
1664
- if (!Object.hasOwn(source, key)) throw new Error("An OpenAPI reference is missing.");
1665
- value = source[key];
1666
- }
1667
- return value;
1668
- }
1669
- function resolved(doc, value) {
1670
- let result = object(value);
1671
- const seen = /* @__PURE__ */ new Set();
1672
- while (typeof result.$ref == "string") {
1673
- if (seen.has(result.$ref)) throw new Error("Circular non-schema reference is unsupported.");
1674
- seen.add(result.$ref);
1675
- const { $ref, ...siblings } = result;
1676
- result = {
1677
- ...object(pointer(doc, $ref)),
1678
- ...siblings
1679
- };
1680
- }
1681
- return result;
1682
- }
1683
- function listOperations(documentValue) {
1684
- const doc = parseOpenApi(documentValue);
1685
- return Object.entries(object(doc.paths)).flatMap(([path, value]) => {
1686
- const item = resolved(doc, value);
1687
- return methods.filter((method) => item[method] != null).map((method) => {
1688
- const op = object(item[method]);
1689
- return {
1690
- method,
1691
- path,
1692
- label: String(op.summary ?? op.operationId ?? `${method.toUpperCase()} ${path}`),
1693
- tag: String(op.tags?.[0] ?? "")
1694
- };
1695
- });
1696
- });
1697
- }
1698
- function operation(doc, path, method) {
1699
- const item = resolved(doc, object(doc.paths)[path]);
1700
- if (!methods.includes(method) || item[method] == null) throw new Error("The selected operation is no longer available.");
1701
- return {
1702
- item,
1703
- op: object(item[method])
1704
- };
1705
- }
1706
- function servers(value, path, method) {
1707
- const doc = parseOpenApi(value);
1708
- const { item, op } = operation(doc, path, method);
1709
- const entries = op.servers ?? item.servers ?? doc.servers;
1710
- if (!Array.isArray(entries) || entries.length == 0) return [{ url: "/" }];
1711
- return entries.map(object);
1712
- }
1713
- function serverAddress(server, sourceUrl, variables = {}) {
1714
- return httpUrl(String(server.url).replace(/\{([^}]+)\}/g, (_, name) => {
1715
- const definition = object(object(server.variables)[name]);
1716
- const value = variables[name] ?? definition.default;
1717
- if (typeof value != "string" || Array.isArray(definition.enum) && !definition.enum.includes(value)) throw new Error("A server variable is invalid.");
1718
- return value;
1719
- }), sourceUrl);
1720
- }
1721
- function securityOptions(value, path, method) {
1722
- const doc = parseOpenApi(value);
1723
- const { op } = operation(doc, path, method);
1724
- const requirements = op.security ?? doc.security ?? [];
1725
- if (!Array.isArray(requirements)) throw new Error("Invalid security requirements.");
1726
- if (!requirements.length) return [{
1727
- label: "None",
1728
- auth: []
1729
- }];
1730
- return requirements.map((entry) => {
1731
- const names = Object.keys(object(entry));
1732
- const label = names.join(" + ") || "None";
1733
- try {
1734
- if (!names.length) return {
1735
- label,
1736
- auth: []
1737
- };
1738
- const schemes = object(object(doc.components).securitySchemes);
1739
- return {
1740
- label,
1741
- auth: names.map((id) => {
1742
- const scheme = resolved(doc, schemes[id]);
1743
- if (scheme.type == "http" && ["bearer", "basic"].includes(String(scheme.scheme).toLowerCase())) return {
1744
- id,
1745
- type: String(scheme.scheme).toLowerCase()
1746
- };
1747
- if (scheme.type == "apiKey" && (scheme.in == "header" || scheme.in == "query") && typeof scheme.name == "string") return {
1748
- id,
1749
- type: "apiKey",
1750
- name: scheme.name,
1751
- in: scheme.in
1752
- };
1753
- throw new Error("This security scheme is unsupported. Supply an access token using manual Bearer authentication if applicable.");
1754
- })
1755
- };
1756
- } catch (error) {
1757
- return {
1758
- label,
1759
- error: error.message
1760
- };
1761
- }
1762
- });
1763
- }
1764
- function snapshot$7(documentValue, path, method) {
1765
- const doc = parseOpenApi(documentValue);
1766
- const { item, op } = operation(doc, path, method);
1767
- const security = op.security ?? doc.security ?? [];
1768
- const result = {
1769
- openapi: doc.openapi,
1770
- paths: { [path]: {
1771
- [method]: op,
1772
- ...item.parameters == null ? {} : { parameters: item.parameters }
1773
- } },
1774
- servers: servers(doc, path, method),
1775
- security
1776
- };
1777
- const visited = /* @__PURE__ */ new Set();
1778
- function copy(ref) {
1779
- if (visited.has(ref)) return;
1780
- visited.add(ref);
1781
- const value = pointer(doc, ref);
1782
- const keys = decodeURIComponent(ref.slice(2)).split("/").map((part) => part.replace(/~1/g, "/").replace(/~0/g, "~"));
1783
- if (keys.some((key) => [
1784
- "__proto__",
1785
- "constructor",
1786
- "prototype"
1787
- ].includes(key))) throw new Error("Unsupported reference key.");
1788
- let target = result;
1789
- for (const key of keys.slice(0, -1)) {
1790
- if (!Object.hasOwn(target, key)) target[key] = {};
1791
- target = object(target[key]);
1792
- }
1793
- target[keys.at(-1)] = structuredClone(value);
1794
- visit(value);
1795
- }
1796
- function visit(value) {
1797
- if (value == null || typeof value != "object") return;
1798
- if (Array.isArray(value)) {
1799
- value.forEach(visit);
1800
- return;
1801
- }
1802
- if (typeof object(value).$ref == "string") copy(object(value).$ref);
1803
- for (const [key, child] of Object.entries(value)) if (![
1804
- "example",
1805
- "examples",
1806
- "default"
1807
- ].includes(key)) visit(child);
1808
- }
1809
- visit(result);
1810
- for (const entry of security) for (const name of Object.keys(object(entry))) copy(`#/components/securitySchemes/${name.replace(/~/g, "~0").replace(/\//g, "~1")}`);
1811
- return structuredClone(result);
1812
- }
1813
- function schema$1(doc, schemaValue) {
1814
- const defs = {};
1815
- const ids = /* @__PURE__ */ new Map();
1816
- function convert(value) {
1817
- if (typeof value == "boolean") return value;
1818
- const source = object(value);
1819
- if (source.format == "binary" || source.$dynamicRef != null || source.$id != null) throw new Error("Binary and dynamically scoped schemas are unsupported.");
1820
- const result = {};
1821
- for (const [key, child] of Object.entries(source)) {
1822
- if ([
1823
- "nullable",
1824
- "example",
1825
- "xml",
1826
- "discriminator",
1827
- "__proto__"
1828
- ].includes(key)) continue;
1829
- if (key == "$ref") {
1830
- if (typeof child != "string") throw new Error("Invalid schema reference.");
1831
- let id = ids.get(child);
1832
- if (id == null) {
1833
- id = `s${ids.size}`;
1834
- ids.set(child, id);
1835
- defs[id] = convert(pointer(doc, child));
1836
- }
1837
- result.$ref = `#/$defs/${id}`;
1838
- } else if ([
1839
- "properties",
1840
- "patternProperties",
1841
- "$defs",
1842
- "definitions",
1843
- "dependentSchemas"
1844
- ].includes(key)) result[key] = Object.fromEntries(Object.entries(object(child)).map(([name, childSchema]) => [name, convert(childSchema)]));
1845
- else if ([
1846
- "allOf",
1847
- "anyOf",
1848
- "oneOf",
1849
- "prefixItems"
1850
- ].includes(key)) {
1851
- if (!Array.isArray(child)) throw new Error("Invalid schema composition.");
1852
- result[key] = child.map(convert);
1853
- } else if ([
1854
- "items",
1855
- "additionalProperties",
1856
- "not",
1857
- "if",
1858
- "then",
1859
- "else",
1860
- "contains",
1861
- "propertyNames",
1862
- "unevaluatedProperties"
1863
- ].includes(key)) result[key] = convert(child);
1864
- else result[key] = child;
1865
- }
1866
- if (source.nullable === true) return { anyOf: [result, { type: "null" }] };
1867
- for (const key of ["minimum", "maximum"]) {
1868
- const exclusive = key == "minimum" ? "exclusiveMinimum" : "exclusiveMaximum";
1869
- if (typeof result[exclusive] == "boolean") {
1870
- if (result[exclusive] && typeof result[key] == "number") {
1871
- result[exclusive] = result[key];
1872
- delete result[key];
1873
- } else delete result[exclusive];
1874
- }
1875
- }
1876
- return result;
1877
- }
1878
- let converted = convert(schemaValue);
1879
- if (typeof converted == "object" && converted != null && typeof object(converted).$ref == "string") {
1880
- const id = String(object(converted).$ref).slice(8);
1881
- const { $ref: _ref, ...siblings } = object(converted);
1882
- converted = {
1883
- ...object(defs[id]),
1884
- ...siblings
1885
- };
1886
- }
1887
- if (typeof converted == "boolean") return converted;
1888
- return {
1889
- $schema: "https://json-schema.org/draft/2020-12/schema",
1890
- ...object(converted),
1891
- ...Object.keys(defs).length ? { $defs: defs } : {}
1892
- };
1893
- }
1894
- function parameters(config) {
1895
- const doc = parseOpenApi(config.document);
1896
- const { item, op } = operation(doc, config.path, config.method);
1897
- const entries = /* @__PURE__ */ new Map();
1898
- for (const value of [...item.parameters ?? [], ...op.parameters ?? []]) {
1899
- const p = resolved(doc, value);
1900
- if (![
1901
- "path",
1902
- "query",
1903
- "header"
1904
- ].includes(String(p.in)) || typeof p.name != "string" || p.content != null) throw new Error("Only schema-based path, query and header parameters are supported.");
1905
- if (p.allowReserved === true) throw new Error("allowReserved parameters are unsupported.");
1906
- if ((p.style ?? (p.in == "query" ? "form" : "simple")) != (p.in == "query" ? "form" : "simple")) throw new Error("Only form query and simple path/header serialization are supported.");
1907
- entries.set(`${p.in}.${p.in == "header" ? p.name.toLowerCase() : p.name}`, p);
1908
- }
1909
- return [...entries.values()];
1910
- }
1911
- function jsonContent(doc, value) {
1912
- const content = resolved(doc, value);
1913
- const media = object(content.content);
1914
- const mediaType = media["application/json"] != null ? "application/json" : Object.keys(media).find((key) => /^application\/.+\+json$/.test(key));
1915
- const json = mediaType == null ? void 0 : media[mediaType];
1916
- if (json == null) throw new Error("Only JSON request and response bodies are supported.");
1917
- return {
1918
- schema: schema$1(doc, object(json).schema ?? {}),
1919
- required: content.required === true,
1920
- mediaType
1921
- };
1922
- }
1923
- function authHandles(auth) {
1924
- return auth.flatMap((scheme) => scheme.type == "basic" ? [`auth.${scheme.id}.username`, `auth.${scheme.id}.password`] : [`auth.${scheme.id}.token`]);
1925
- }
1926
- function openApiTask(config, name = "OpenAPI") {
1927
- if (!config.path) return {
1928
- name,
1929
- executor: config,
1930
- inputs: [],
1931
- outputs: []
1932
- };
1933
- const doc = parseOpenApi(config.document);
1934
- const { op } = operation(doc, config.path, config.method);
1935
- const params = parameters(config);
1936
- const inputs = params.map((p) => {
1937
- const jsonSchema = schema$1(doc, p.schema ?? {});
1938
- const defaultValue = typeof jsonSchema == "boolean" ? void 0 : object(jsonSchema).default;
1939
- return {
1940
- handle: `${p.in}.${p.name}`,
1941
- jsonSchema,
1942
- nullable: p.required !== true && p.in != "path" || matchesSchema(null, jsonSchema),
1943
- ...typeof p.description == "string" ? { description: p.description } : {},
1944
- ...defaultValue === void 0 ? {} : { value: defaultValue }
1945
- };
1946
- });
1947
- if (op.requestBody != null) {
1948
- if (config.method == "get" || config.method == "head") throw new Error("GET and HEAD request bodies are unsupported.");
1949
- const body = jsonContent(doc, op.requestBody);
1950
- inputs.push({
1951
- handle: "body",
1952
- jsonSchema: body.schema,
1953
- nullable: !body.required || matchesSchema(null, body.schema)
1954
- });
1955
- }
1956
- const occupied = new Set(params.map((p) => `${p.in}.${p.in == "header" ? String(p.name).toLowerCase() : p.name}`));
1957
- for (const auth of config.auth) {
1958
- const location = auth.type == "apiKey" ? `${auth.in}.${auth.in == "header" ? auth.name?.toLowerCase() : auth.name}` : "header.authorization";
1959
- if (occupied.has(location)) throw new Error("Authentication conflicts with a parameter or another security scheme.");
1960
- if (auth.type == "apiKey" && (!auth.name || !["header", "query"].includes(auth.in ?? ""))) throw new Error("API Key requires a name and location.");
1961
- occupied.add(location);
1962
- }
1963
- inputs.push(...authHandles(config.auth).map((handle) => ({
1964
- handle,
1965
- jsonSchema: { type: "string" },
1966
- nullable: false
1967
- })));
1968
- const responses = object(op.responses);
1969
- const schemas = [];
1970
- for (const [status, response] of Object.entries(responses)) if (/^2\d\d$|^2XX$/.test(status) || status == "default") {
1971
- const r = resolved(doc, response);
1972
- if (r.content == null) schemas.push({ type: "null" });
1973
- else {
1974
- jsonContent(doc, r);
1975
- for (const [mediaType, media] of Object.entries(object(r.content))) if (/^application\/(json|.+\+json)$/.test(mediaType)) schemas.push(schema$1(doc, object(media).schema ?? {}));
1976
- }
1977
- }
1978
- if (!schemas.length) throw new Error("A successful JSON response definition is required.");
1979
- return {
1980
- name,
1981
- executor: config,
1982
- inputs,
1983
- outputs: [
1984
- {
1985
- handle: "body",
1986
- jsonSchema: schemas.length == 1 ? schemas[0] : {
1987
- $schema: "https://json-schema.org/draft/2020-12/schema",
1988
- anyOf: schemas.map((s, index) => inlineSchema(s, index))
1989
- },
1990
- nullable: config.method == "head" || schemas.some((item) => matchesSchema(null, item))
1991
- },
1992
- {
1993
- handle: "statusCode",
1994
- jsonSchema: { type: "integer" },
1995
- nullable: false
1996
- },
1997
- {
1998
- handle: "headers",
1999
- jsonSchema: {
2000
- type: "object",
2001
- additionalProperties: { type: "string" }
2002
- },
2003
- nullable: false
2004
- }
2005
- ]
2006
- };
2007
- }
2008
- function inlineSchema(value, index) {
2009
- if (Array.isArray(value)) return value.map((item) => inlineSchema(item, index));
2010
- if (value == null || typeof value != "object") return value;
2011
- return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, key == "$ref" && typeof child == "string" && child.startsWith("#/") ? `#/anyOf/${index}/${child.slice(2)}` : inlineSchema(child, index)]));
949
+ function inlineSchema(value, index) {
950
+ if (Array.isArray(value)) return value.map((item) => inlineSchema(item, index));
951
+ if (value == null || typeof value != "object") return value;
952
+ return Object.fromEntries(Object.entries(value).map(([key, child]) => [key, key == "$ref" && typeof child == "string" && child.startsWith("#/") ? `#/anyOf/${index}/${child.slice(2)}` : inlineSchema(child, index)]));
2012
953
  }
2013
954
  /** The canvas validator and property panel share the same configuration contract. */
2014
955
  function openApiFieldIssues(task) {
@@ -2075,7 +1016,7 @@ var authenticationSchema = union([
2075
1016
  in: _enum(["header", "query"])
2076
1017
  })
2077
1018
  ]);
2078
- strictObject({
1019
+ var authoringOpenApiSchema = strictObject({
2079
1020
  sourceUrl: string$1().min(1),
2080
1021
  path: string$1().min(1),
2081
1022
  method: string$1().min(1),
@@ -2172,37 +1113,54 @@ var when = union([
2172
1113
  all,
2173
1114
  strictObject({ any: array(union([expression, all])) })
2174
1115
  ]);
2175
- strictObject({}), strictObject({ sourceFlowIds: array(id$1).optional() }), authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(), strictObject({ schedule: authoringDefinitionSchemas.schedule }), strictObject({
2176
- key: id$1,
2177
- connectionId: id$1.optional(),
2178
- schedule: authoringDefinitionSchemas.schedule
2179
- }), strictObject({
2180
- key: id$1,
2181
- connectionId: id$1.optional()
2182
- }), strictObject({
2183
- inputs: inputFields,
2184
- outputs: outputFields,
2185
- capabilities: authoringDefinitionSchemas.capabilities.optional()
2186
- }), authoringDefinitionSchemas.connector.strict(), authoringDefinitionSchemas.agent.omit({
2187
- prompt: true,
2188
- tools: true
2189
- }).extend({
2190
- inputs: inputFields,
2191
- resultSchema: json$1.describe("JSON schema of the final result. Defaults to text. The tool manages the output definition; references can omit port."),
2192
- tools: array(agentTool$1),
2193
- notification: notification.optional()
2194
- }).strict(), authoringLlmConfiguration.extend({ inputs: inputFields }), authoringDefinitionSchemas.decision, strictObject({
2195
- match: _enum(["first", "all"]),
2196
- branches: array(strictObject({
2197
- name: id$1,
2198
- description: string$1().optional(),
2199
- when
2200
- }))
2201
- }), strictObject({
2202
- values: patch,
2203
- outputs: outputFields
2204
- }), strictObject({ inputs: inputFields }), strictObject({ inputs: inputFields });
2205
- var metadata = {
1116
+ var authoringConfigurations = {
1117
+ manual: strictObject({}),
1118
+ error: strictObject({ sourceFlowIds: array(id$1).optional() }),
1119
+ webhook: authoringDefinitionSchemas.webhook.omit({ bodyFields: true }).extend({ body: inputFields }).strict(),
1120
+ cron: strictObject({ schedule: authoringDefinitionSchemas.schedule }),
1121
+ poll: strictObject({
1122
+ key: id$1,
1123
+ connectionId: id$1.optional(),
1124
+ schedule: authoringDefinitionSchemas.schedule
1125
+ }),
1126
+ integration: strictObject({
1127
+ key: id$1,
1128
+ connectionId: id$1.optional()
1129
+ }),
1130
+ code: strictObject({
1131
+ inputs: inputFields,
1132
+ outputs: outputFields,
1133
+ capabilities: authoringDefinitionSchemas.capabilities.optional()
1134
+ }),
1135
+ connector: authoringDefinitionSchemas.connector.strict(),
1136
+ openapi: authoringOpenApiSchema,
1137
+ agent: authoringDefinitionSchemas.agent.omit({
1138
+ prompt: true,
1139
+ tools: true
1140
+ }).extend({
1141
+ inputs: inputFields,
1142
+ resultSchema: json$1.describe("JSON schema of the final result. Defaults to text. The tool manages the output definition; references can omit port."),
1143
+ tools: array(agentTool$1),
1144
+ notification: notification.optional()
1145
+ }).strict(),
1146
+ llm: authoringLlmConfiguration.extend({ inputs: inputFields }),
1147
+ decision: authoringDefinitionSchemas.decision,
1148
+ condition: strictObject({
1149
+ match: _enum(["first", "all"]),
1150
+ branches: array(strictObject({
1151
+ name: id$1,
1152
+ description: string$1().optional(),
1153
+ when
1154
+ }))
1155
+ }),
1156
+ value: strictObject({
1157
+ values: patch,
1158
+ outputs: outputFields
1159
+ }),
1160
+ wait: strictObject({ inputs: inputFields }),
1161
+ approval: strictObject({ inputs: inputFields })
1162
+ };
1163
+ var metadata$1 = {
2206
1164
  name: id$1.optional(),
2207
1165
  description: string$1().optional(),
2208
1166
  icon: string$1().optional(),
@@ -2210,7 +1168,7 @@ var metadata = {
2210
1168
  timeoutMs: number().nonnegative().optional()
2211
1169
  };
2212
1170
  var updates = strictObject({
2213
- ...metadata,
1171
+ ...metadata$1,
2214
1172
  config: patch.optional().describe("Recursively merge configuration; omitted fields remain unchanged and arrays replace as a whole. This includes schema objects: {} does not clear an existing schema. Use clear paths to remove fields, e.g. [\"config\",\"inputs\",\"amount\",\"schema\",\"type\"].")
2215
1173
  });
2216
1174
  var authoringEditSchema = discriminatedUnion("op", [
@@ -2351,6 +1309,142 @@ var authoringSearchResponse = object$1({
2351
1309
  version: literal(1)
2352
1310
  });
2353
1311
  //#endregion
1312
+ //#region src/control/common/publicationDecoders.ts
1313
+ function publication$7(value) {
1314
+ const source = record$1(value);
1315
+ const liveEnd = source.liveEnd == null ? void 0 : record$1(source.liveEnd);
1316
+ if (liveEnd != null && typeof liveEnd.enabled != "boolean") return invalidResponse();
1317
+ const operation = source.operation;
1318
+ const sourcePublicationId = source.sourcePublicationId;
1319
+ if (source.version != 1) return invalidResponse();
1320
+ if (operation != "publish" && operation != "rollback") return invalidResponse();
1321
+ if (sourcePublicationId != null && typeof sourcePublicationId != "string") return invalidResponse();
1322
+ return {
1323
+ ...liveEnd == null ? {} : { liveEnd: {
1324
+ enabled: liveEnd.enabled,
1325
+ endedAt: string(liveEnd.endedAt)
1326
+ } },
1327
+ actorId: string(source.actorId),
1328
+ closureDigest: string(source.closureDigest),
1329
+ createdAt: string(source.createdAt),
1330
+ engineContract: string(source.engineContract),
1331
+ flowId: string(source.flowId),
1332
+ modelVersion: integer(source.modelVersion),
1333
+ operation,
1334
+ publicationId: string(source.publicationId),
1335
+ sharedAccessDigest: string(source.sharedAccessDigest),
1336
+ revisionDigest: string(source.revisionDigest),
1337
+ revisionId: string(source.revisionId),
1338
+ ...sourcePublicationId == null ? {} : { sourcePublicationId },
1339
+ version: 1
1340
+ };
1341
+ }
1342
+ function publishOperation(value) {
1343
+ const source = record$1(value);
1344
+ const status = source.status;
1345
+ const common = {
1346
+ createdAt: string(source.createdAt),
1347
+ flowId: string(source.flowId),
1348
+ operationId: string(source.operationId),
1349
+ revisionId: string(source.revisionId),
1350
+ updatedAt: string(source.updatedAt),
1351
+ version: 1
1352
+ };
1353
+ if (source.version != 1) return invalidResponse();
1354
+ switch (status) {
1355
+ case "pending":
1356
+ exact(source, [
1357
+ "createdAt",
1358
+ "flowId",
1359
+ "operationId",
1360
+ "revisionId",
1361
+ "status",
1362
+ "updatedAt",
1363
+ "version"
1364
+ ]);
1365
+ return {
1366
+ ...common,
1367
+ status
1368
+ };
1369
+ case "succeeded":
1370
+ exact(source, [
1371
+ "createdAt",
1372
+ "flowId",
1373
+ "operationId",
1374
+ "publicationId",
1375
+ "revisionId",
1376
+ "status",
1377
+ "updatedAt",
1378
+ "version"
1379
+ ]);
1380
+ return {
1381
+ ...common,
1382
+ publicationId: string(source.publicationId),
1383
+ status
1384
+ };
1385
+ case "failed": {
1386
+ exact(source, [
1387
+ "createdAt",
1388
+ "flowId",
1389
+ "issue",
1390
+ "operationId",
1391
+ "revisionId",
1392
+ "status",
1393
+ "updatedAt",
1394
+ "version"
1395
+ ]);
1396
+ const issue = record$1(source.issue);
1397
+ const nodeId = issue.nodeId;
1398
+ exact(issue, [
1399
+ "code",
1400
+ "message",
1401
+ ...nodeId == null ? [] : ["nodeId"]
1402
+ ]);
1403
+ return {
1404
+ ...common,
1405
+ issue: {
1406
+ code: string(issue.code),
1407
+ message: string(issue.message),
1408
+ ...nodeId == null ? {} : { nodeId: string(nodeId) }
1409
+ },
1410
+ status
1411
+ };
1412
+ }
1413
+ default: return invalidResponse();
1414
+ }
1415
+ }
1416
+ function live(value) {
1417
+ const source = record$1(value);
1418
+ const status = source.status;
1419
+ const candidate = source.publication;
1420
+ if (source.version != 1 || typeof source.hasUnpublishedChanges != "boolean") return invalidResponse();
1421
+ if (status != "not-published" && status != "runnable" && status != "suspended") return invalidResponse();
1422
+ if (status == "not-published" && candidate !== null) return invalidResponse();
1423
+ if (status != "not-published" && candidate === null) return invalidResponse();
1424
+ return {
1425
+ flowId: string(source.flowId),
1426
+ hasUnpublishedChanges: source.hasUnpublishedChanges,
1427
+ publication: candidate === null ? null : publication$7(candidate),
1428
+ revision: integer(source.revision),
1429
+ status,
1430
+ version: 1
1431
+ };
1432
+ }
1433
+ function publicationPage(value) {
1434
+ const source = record$1(value);
1435
+ const nextCursor = source.nextCursor;
1436
+ const total = source.total;
1437
+ if (source.version != 1 || !Array.isArray(source.publications)) return invalidResponse();
1438
+ if (nextCursor != null && typeof nextCursor != "string") return invalidResponse();
1439
+ if (total != null && !Number.isSafeInteger(total)) return invalidResponse();
1440
+ return {
1441
+ ...nextCursor == null ? {} : { nextCursor },
1442
+ publications: source.publications.map(publication$7),
1443
+ ...total == null ? {} : { total },
1444
+ version: 1
1445
+ };
1446
+ }
1447
+ //#endregion
2354
1448
  //#region src/trigger/common/configSchema.ts
2355
1449
  var configInputsSchema = array(union([strictObject({
2356
1450
  handle: string$1().min(1),
@@ -2533,452 +1627,1011 @@ function pollTriggerTestResult(value) {
2533
1627
  };
2534
1628
  }
2535
1629
  //#endregion
2536
- //#region src/control/common/publicationResources.ts
2537
- function context(source) {
2538
- if (source.version != 1 || source.status != "live" && source.status != "historical") return invalidResponse();
2539
- if (source.status == "live" ? typeof source.enabled != "boolean" : source.enabled !== void 0) return invalidResponse();
1630
+ //#region src/control/common/liveDetails.ts
1631
+ var metadata = {
1632
+ nodeId: string$1().min(1),
1633
+ name: string$1(),
1634
+ description: string$1().optional()
1635
+ };
1636
+ var binding = unknown().transform(triggerBinding);
1637
+ var provider = {
1638
+ provider: string$1().min(1),
1639
+ inputs: record$2(string$1(), discriminatedUnion("kind", [strictObject({
1640
+ kind: literal("value"),
1641
+ value: json$2()
1642
+ }), strictObject({ kind: literal("unset") })]))
1643
+ };
1644
+ var entrySchema = discriminatedUnion("type", [
1645
+ strictObject({
1646
+ ...metadata,
1647
+ type: literal("manual"),
1648
+ config: authoringConfigurations.manual
1649
+ }),
1650
+ strictObject({
1651
+ ...metadata,
1652
+ type: literal("webhook"),
1653
+ config: authoringConfigurations.webhook,
1654
+ binding
1655
+ }),
1656
+ strictObject({
1657
+ ...metadata,
1658
+ type: literal("cron"),
1659
+ config: authoringConfigurations.cron,
1660
+ binding
1661
+ }),
1662
+ strictObject({
1663
+ ...metadata,
1664
+ type: literal("error"),
1665
+ config: authoringConfigurations.error,
1666
+ binding
1667
+ }),
1668
+ strictObject({
1669
+ ...metadata,
1670
+ ...provider,
1671
+ type: literal("poll"),
1672
+ config: authoringConfigurations.poll,
1673
+ binding
1674
+ }),
1675
+ strictObject({
1676
+ ...metadata,
1677
+ ...provider,
1678
+ type: literal("integration"),
1679
+ config: authoringConfigurations.integration,
1680
+ binding
1681
+ })
1682
+ ]);
1683
+ function decodeLiveDetails(value) {
1684
+ const source = record$1(value);
1685
+ const flowId = string(source.flowId);
1686
+ if (source.version != 1 || !Array.isArray(source.entries)) return invalidResponse();
1687
+ if (source.publication === null) {
1688
+ if (source.status != "not-published" || source.entries.length != 0 || Object.hasOwn(source, "enabled")) return invalidResponse();
1689
+ return {
1690
+ flowId,
1691
+ publication: null,
1692
+ status: "not-published",
1693
+ entries: [],
1694
+ version: 1
1695
+ };
1696
+ }
1697
+ const current = publication$7(source.publication);
1698
+ const status = source.status;
1699
+ if (current.flowId != flowId || typeof source.enabled != "boolean") return invalidResponse();
1700
+ if (status != "runnable" && status != "suspended") return invalidResponse();
1701
+ if (!source.enabled && source.status == "runnable") return invalidResponse();
2540
1702
  return {
2541
- flowId: string(source.flowId),
2542
- publicationId: string(source.publicationId),
2543
- revisionId: string(source.revisionId),
2544
- status: source.status,
2545
- ...source.enabled == null ? {} : { enabled: source.enabled },
1703
+ flowId,
1704
+ publication: current,
1705
+ status,
1706
+ enabled: source.enabled,
1707
+ entries: decodeEntries(source.entries, current),
2546
1708
  version: 1
2547
1709
  };
2548
1710
  }
2549
- function resource$7(value, scope) {
1711
+ /** Both producers and consumers enforce the same published-entry invariants. */
1712
+ function decodeEntries(values, current) {
1713
+ const parsed = array(entrySchema).safeParse(values);
1714
+ if (!parsed.success) return invalidResponse();
1715
+ const ids = /* @__PURE__ */ new Set();
1716
+ for (const entry of parsed.data) {
1717
+ if (ids.has(entry.nodeId)) return invalidResponse();
1718
+ ids.add(entry.nodeId);
1719
+ if (entry.type != "manual" && (entry.binding.flowId != current.flowId || entry.binding.triggerNodeId != entry.nodeId || entry.binding.kind != entry.type || entry.binding.currentPublicationId != current.publicationId || entry.binding.currentRevisionId != current.revisionId)) return invalidResponse();
1720
+ if (entry.type == "webhook" && (!entry.binding.endpointUrl || !webhookSupportsBody(entry.config.method) && Object.keys(entry.config.body).length > 0)) return invalidResponse();
1721
+ }
1722
+ return parsed.data;
1723
+ }
1724
+ //#endregion
1725
+ //#region src/control/common/providerIconSprite.ts
1726
+ /** Optional artwork must never make an otherwise usable catalog unavailable. */
1727
+ function providerIconAppearance(metadata, position) {
1728
+ if (!metadata || typeof metadata != "object" || !position || typeof position != "object") return {};
1729
+ const m = metadata;
1730
+ const p = position;
1731
+ if (typeof m.version != "string" || ![
1732
+ m.pixelRatio,
1733
+ m.iconSize,
1734
+ m.width,
1735
+ m.height
1736
+ ].every((v) => Number.isInteger(v) && v > 0) || ![
1737
+ m.bleed,
1738
+ p.x,
1739
+ p.y
1740
+ ].every((v) => Number.isInteger(v) && v >= 0) || p.x + m.iconSize > m.width || p.y + m.iconSize > m.height) return {};
1741
+ try {
1742
+ for (const url of [m.lightUrl, m.darkUrl]) if (typeof url != "string" || ![
1743
+ "https:",
1744
+ "http:",
1745
+ "data:"
1746
+ ].includes(new URL(url).protocol)) return {};
1747
+ } catch {
1748
+ return {};
1749
+ }
1750
+ return {
1751
+ iconSprite: m,
1752
+ iconSpritePosition: {
1753
+ x: p.x,
1754
+ y: p.y
1755
+ }
1756
+ };
1757
+ }
1758
+ new TextEncoder();
1759
+ //#endregion
1760
+ //#region src/control/common/providerAccess.ts
1761
+ var sourceSchema = discriminatedUnion("kind", [strictObject({ kind: literal("admin-delegation") }), strictObject({
1762
+ kind: literal("policy"),
1763
+ ruleId: string$1().min(1).nullable()
1764
+ })]);
1765
+ function parseProviderAccessSource(value) {
1766
+ return sourceSchema.parse(value);
1767
+ }
1768
+ //#endregion
1769
+ //#region src/control/common/connectorDecoders.ts
1770
+ function accessPermissions(value) {
2550
1771
  const source = record$1(value);
2551
- const type = source.type;
2552
- if (source.kind != "trigger" || type != "webhook" && type != "cron" && type != "poll" && type != "integration" && type != "error") return invalidResponse();
2553
- if (source.description != null && typeof source.description != "string") return invalidResponse();
2554
- const resourceId = string(source.resourceId);
2555
- const runtime = source.runtime == null ? void 0 : triggerBinding(source.runtime);
2556
- if (runtime != null && (scope.status != "live" || runtime.flowId != scope.flowId || runtime.currentPublicationId != scope.publicationId || runtime.currentRevisionId != scope.revisionId || runtime.triggerNodeId != resourceId || runtime.kind != type)) return invalidResponse();
1772
+ exact(source, [
1773
+ "actionIds",
1774
+ "allActions",
1775
+ "triggerIds",
1776
+ "allTriggers",
1777
+ "configured",
1778
+ "proxy"
1779
+ ]);
1780
+ if (!Array.isArray(source.actionIds)) return invalidResponse("permissions.actionIds: expected an array.");
1781
+ if (!Array.isArray(source.triggerIds)) return invalidResponse("permissions.triggerIds: expected an array.");
1782
+ if (typeof source.allActions != "boolean") return invalidResponse("permissions.allActions: expected a boolean.");
1783
+ if (typeof source.allTriggers != "boolean") return invalidResponse("permissions.allTriggers: expected a boolean.");
1784
+ if (typeof source.configured != "boolean") return invalidResponse("permissions.configured: expected a boolean.");
1785
+ if (typeof source.proxy != "boolean") return invalidResponse("permissions.proxy: expected a boolean.");
1786
+ const actionIds = source.actionIds.map(string);
1787
+ const triggerIds = source.triggerIds.map(string);
1788
+ if (new Set(actionIds).size != actionIds.length) return invalidResponse("permissions.actionIds: duplicate IDs.");
1789
+ if (source.allActions && actionIds.length != 0) return invalidResponse("permissions.actionIds: must be empty when allActions is true.");
1790
+ if (new Set(triggerIds).size != triggerIds.length) return invalidResponse("permissions.triggerIds: duplicate IDs.");
1791
+ if (source.allTriggers && triggerIds.length != 0) return invalidResponse("permissions.triggerIds: must be empty when allTriggers is true.");
1792
+ if (source.proxy && (!source.allActions || !source.allTriggers || source.configured)) return invalidResponse("permissions.proxy: requires allActions=true, allTriggers=true and configured=false.");
1793
+ return {
1794
+ actionIds,
1795
+ triggerIds,
1796
+ allTriggers: source.allTriggers,
1797
+ allActions: source.allActions,
1798
+ configured: source.configured,
1799
+ proxy: source.proxy
1800
+ };
1801
+ }
1802
+ function accessBinding(value, candidate) {
1803
+ const source = record$1(value);
1804
+ const policyRevision = source.policyRevision;
1805
+ const status = source.status;
1806
+ const isDefault = source.isDefault;
1807
+ const legacy = Object.hasOwn(source, "displayName") && !Object.hasOwn(source, "connectionDisplayName");
1808
+ const permissions = candidate && Object.hasOwn(source, "permissions") ? accessPermissions(source.permissions) : void 0;
1809
+ const permissionGroupName = source.permissionGroupName;
1810
+ exact(source, [
1811
+ "accessBindingId",
1812
+ "connectionId",
1813
+ "source",
1814
+ legacy ? "displayName" : "connectionDisplayName",
1815
+ ...candidate && Object.hasOwn(source, "isDefault") ? ["isDefault"] : [],
1816
+ ...candidate && permissions != null ? ["permissions"] : [],
1817
+ ...Object.hasOwn(source, "permissionGroupName") ? ["permissionGroupName"] : [],
1818
+ ...policyRevision == null ? [] : ["policyRevision"],
1819
+ "providerId",
1820
+ ...candidate ? [] : ["status"]
1821
+ ]);
1822
+ if (policyRevision != null && typeof policyRevision != "string") return invalidResponse("policyRevision: expected a string.");
1823
+ if (candidate && isDefault !== void 0 && typeof isDefault != "boolean") return invalidResponse("isDefault: expected a boolean.");
1824
+ if (permissionGroupName !== void 0 && permissionGroupName !== null && typeof permissionGroupName != "string") return invalidResponse("permissionGroupName: expected a string or null.");
1825
+ if (!candidate && status != "active" && status != "forbidden" && status != "invalid" && status != "missing") return invalidResponse();
1826
+ let bindingSource;
1827
+ try {
1828
+ bindingSource = parseProviderAccessSource(source.source);
1829
+ } catch {
1830
+ return invalidResponse("source: expected { kind: 'admin-delegation' } or { kind: 'policy', ruleId: string | null }.");
1831
+ }
1832
+ return {
1833
+ accessBindingId: string(source.accessBindingId),
1834
+ connectionId: string(source.connectionId),
1835
+ source: bindingSource,
1836
+ connectionDisplayName: string(legacy ? source.displayName : source.connectionDisplayName),
1837
+ ...candidate && typeof isDefault == "boolean" ? { isDefault } : {},
1838
+ ...permissions == null ? {} : { permissions },
1839
+ ...permissionGroupName === void 0 ? {} : { permissionGroupName },
1840
+ ...policyRevision == null ? {} : { policyRevision },
1841
+ providerId: string(source.providerId),
1842
+ ...candidate ? {} : { status }
1843
+ };
1844
+ }
1845
+ function accessMode(value) {
1846
+ if (value != "implicit" && value != "selectable") return invalidResponse("mode: expected implicit or selectable.");
1847
+ return value;
1848
+ }
1849
+ function connectorAccess$7(value) {
1850
+ const source = record$1(value);
1851
+ exact(source, [
1852
+ "accessRevision",
1853
+ "bindings",
1854
+ "mode",
1855
+ "sharedAccessDigest",
1856
+ ..."providerIds" in source ? ["providerIds"] : [],
1857
+ ..."discardedBindingCount" in source ? ["discardedBindingCount"] : [],
1858
+ "version"
1859
+ ]);
1860
+ const accessRevision = integer(source.accessRevision);
1861
+ if (source.version != 1 || accessRevision < 0 || !Array.isArray(source.bindings)) return invalidResponse();
1862
+ if ("providerIds" in source && !Array.isArray(source.providerIds)) return invalidResponse();
1863
+ const providerIds = source.providerIds == null ? void 0 : source.providerIds.map((id) => string(id));
1864
+ if (providerIds != null && new Set(providerIds).size != providerIds.length) return invalidResponse();
1865
+ let discardedBindingCount = source.discardedBindingCount == null ? 0 : integer(source.discardedBindingCount);
1866
+ if (discardedBindingCount < 0) return invalidResponse();
1867
+ const bindings = [];
1868
+ for (const entry of source.bindings) try {
1869
+ bindings.push(accessBinding(entry, false));
1870
+ } catch (error) {
1871
+ if (!(error instanceof ApiError) || error.code != "response.invalid") throw error;
1872
+ if (entry != null && typeof entry == "object" && !Array.isArray(entry) && typeof entry.accessBindingId == "string" && entry.accessBindingId.length > 0 && typeof entry.providerId == "string" && entry.providerId.length > 0) bindings.push({
1873
+ accessBindingId: entry.accessBindingId,
1874
+ providerId: entry.providerId,
1875
+ connectionId: null,
1876
+ source: null,
1877
+ status: "invalid",
1878
+ connectionDisplayName: typeof entry.connectionDisplayName == "string" && entry.connectionDisplayName.length > 0 ? entry.connectionDisplayName : typeof entry.displayName == "string" && entry.displayName.length > 0 ? entry.displayName : entry.providerId,
1879
+ permissionGroupName: typeof entry.permissionGroupName == "string" ? entry.permissionGroupName : null
1880
+ });
1881
+ else discardedBindingCount++;
1882
+ }
1883
+ if (new Set(bindings.map((binding) => binding.accessBindingId)).size != bindings.length) return invalidResponse();
1884
+ return {
1885
+ accessRevision,
1886
+ ...discardedBindingCount == 0 ? {} : { discardedBindingCount },
1887
+ ...providerIds == null ? {} : { providerIds },
1888
+ bindings,
1889
+ mode: accessMode(source.mode),
1890
+ sharedAccessDigest: string(source.sharedAccessDigest),
1891
+ version: 1
1892
+ };
1893
+ }
1894
+ function accessGrants(value) {
1895
+ if (!Array.isArray(value)) return invalidResponse();
1896
+ const bindings = value.map((candidate) => {
1897
+ const entry = record$1(candidate);
1898
+ exact(entry, [
1899
+ "accessBindingId",
1900
+ "connectionId",
1901
+ "providerId",
1902
+ "source",
1903
+ "connectionDisplayName",
1904
+ ..."permissionGroupName" in entry ? ["permissionGroupName"] : []
1905
+ ]);
1906
+ let identity;
1907
+ try {
1908
+ identity = parseProviderAccessSource(entry.source);
1909
+ } catch {
1910
+ return invalidResponse();
1911
+ }
1912
+ if (entry.permissionGroupName != null && typeof entry.permissionGroupName != "string") return invalidResponse();
1913
+ return {
1914
+ accessBindingId: string(entry.accessBindingId),
1915
+ connectionId: string(entry.connectionId),
1916
+ providerId: string(entry.providerId),
1917
+ source: identity,
1918
+ connectionDisplayName: string(entry.connectionDisplayName),
1919
+ ..."permissionGroupName" in entry ? { permissionGroupName: entry.permissionGroupName } : {}
1920
+ };
1921
+ });
1922
+ if (new Set(bindings.map((binding) => binding.accessBindingId)).size != bindings.length) return invalidResponse();
1923
+ return bindings;
1924
+ }
1925
+ function connectorAccessSnapshot(value) {
1926
+ const source = record$1(value);
1927
+ exact(source, [
1928
+ "mode",
1929
+ "sharedAccessDigest",
1930
+ "sharedBindings",
1931
+ "selectedBindings",
1932
+ "version"
1933
+ ]);
1934
+ if (source.version != 2) return invalidResponse();
1935
+ const mode = accessMode(source.mode);
1936
+ const sharedBindings = accessGrants(source.sharedBindings);
1937
+ const selectedBindings = accessGrants(source.selectedBindings);
1938
+ if (mode == "implicit" && (sharedBindings.length > 0 || selectedBindings.length > 0)) return invalidResponse();
1939
+ return {
1940
+ mode,
1941
+ sharedAccessDigest: string(source.sharedAccessDigest),
1942
+ sharedBindings,
1943
+ selectedBindings,
1944
+ version: 2
1945
+ };
1946
+ }
1947
+ function connectorAccessCandidates(value, providerId) {
1948
+ const source = record$1(value);
1949
+ exact(source, [
1950
+ "candidates",
1951
+ "mode",
1952
+ "providerId",
1953
+ "version"
1954
+ ]);
1955
+ if (source.version != 1) return invalidResponse("version: expected 1.");
1956
+ if (string(source.providerId) != providerId) return invalidResponse("providerId: does not match the requested provider.");
1957
+ if (!Array.isArray(source.candidates)) return invalidResponse("candidates: expected an array.");
1958
+ const candidates = source.candidates.map((candidate) => accessBinding(candidate, true));
1959
+ if (candidates.some((candidate) => candidate.providerId != providerId)) return invalidResponse("candidates[].providerId: does not match the requested provider.");
1960
+ if (new Set(candidates.map((candidate) => candidate.accessBindingId)).size != candidates.length) return invalidResponse("candidates[].accessBindingId: duplicate IDs.");
1961
+ return {
1962
+ candidates,
1963
+ mode: accessMode(source.mode),
1964
+ providerId,
1965
+ version: 1
1966
+ };
1967
+ }
1968
+ function connectorAccessCandidatesBatch(value, providerIds) {
1969
+ const source = record$1(value);
1970
+ exact(source, ["results", "version"]);
1971
+ if (source.version != 1) return invalidResponse("version: expected 1.");
1972
+ if (!Array.isArray(source.results)) return invalidResponse("results: expected an array.");
1973
+ const remaining = new Set(providerIds);
1974
+ const results = source.results.map((entry) => {
1975
+ const item = record$1(entry);
1976
+ const providerId = string(item.providerId);
1977
+ if (!remaining.delete(providerId)) return invalidResponse("results[].providerId: duplicate or unrequested provider.");
1978
+ if (!Object.hasOwn(item, "error")) return connectorAccessCandidates(item, providerId);
1979
+ exact(item, ["providerId", "error"]);
1980
+ const error = record$1(item.error);
1981
+ exact(error, ["code", "message"]);
1982
+ return {
1983
+ providerId,
1984
+ error: {
1985
+ code: string(error.code),
1986
+ message: string(error.message)
1987
+ }
1988
+ };
1989
+ });
1990
+ if (remaining.size != 0) return invalidResponse("results: missing requested providers.");
1991
+ return {
1992
+ results,
1993
+ version: 1
1994
+ };
1995
+ }
1996
+ function connection(value) {
1997
+ const source = record$1(value);
1998
+ exact(source, [
1999
+ ...Object.hasOwn(source, "providerAccountId") ? ["providerAccountId"] : [],
2000
+ ...Object.hasOwn(source, "alias") ? ["alias"] : [],
2001
+ ...Object.hasOwn(source, "builtInAccount") ? ["builtInAccount"] : [],
2002
+ "connectionId",
2003
+ "displayName",
2004
+ "isDefault",
2005
+ "serviceId",
2006
+ "status"
2007
+ ]);
2008
+ if (source.builtInAccount !== void 0 && typeof source.builtInAccount != "boolean") return invalidResponse();
2009
+ const status = source.status;
2010
+ if (status != "active" && status != "disconnected" && status != "error" && status != "reauth_required") return invalidResponse();
2011
+ if (typeof source.isDefault != "boolean") return invalidResponse();
2012
+ return {
2013
+ ...source.providerAccountId === void 0 ? {} : { providerAccountId: string(source.providerAccountId) },
2014
+ ...source.alias === void 0 ? {} : { alias: string(source.alias) },
2015
+ ...source.builtInAccount === void 0 ? {} : { builtInAccount: source.builtInAccount },
2016
+ connectionId: string(source.connectionId),
2017
+ displayName: string(source.displayName),
2018
+ isDefault: source.isDefault,
2019
+ serviceId: string(source.serviceId),
2020
+ status
2021
+ };
2022
+ }
2023
+ function port(value, input = false) {
2024
+ const source = record$1(value);
2025
+ const description = source.description;
2026
+ const hasValue = input && Object.hasOwn(source, "value");
2027
+ exact(source, [
2028
+ "jsonSchema",
2029
+ "nullable",
2030
+ ...description == null ? [] : ["description"],
2031
+ ...hasValue ? ["value"] : []
2032
+ ]);
2033
+ if (description != null && typeof description != "string") return invalidResponse();
2034
+ if (typeof source.nullable != "boolean") return invalidResponse();
2035
+ return {
2036
+ ...description == null ? {} : { description },
2037
+ jsonSchema: jsonValue(source.jsonSchema),
2038
+ nullable: source.nullable,
2039
+ ...hasValue ? { value: jsonValue(source.value) } : {}
2040
+ };
2041
+ }
2042
+ function inputPort(value) {
2043
+ return port(value, true);
2044
+ }
2045
+ function ports(value, decode) {
2046
+ return Object.fromEntries(Object.entries(record$1(value)).map(([handle, candidate]) => [handle, decode(candidate)]));
2047
+ }
2048
+ function connectorActionMetadata(value) {
2049
+ const source = record$1(value);
2050
+ const homepageUrl = source.homepageUrl;
2051
+ const icon = source.icon;
2052
+ exact(source, [
2053
+ "actionId",
2054
+ ...Object.hasOwn(source, "operationType") ? ["operationType"] : [],
2055
+ ...Object.hasOwn(source, "inputSchema") ? ["inputSchema"] : [],
2056
+ ...Object.hasOwn(source, "outputSchema") ? ["outputSchema"] : [],
2057
+ "authenticated",
2058
+ "description",
2059
+ ...homepageUrl == null ? [] : ["homepageUrl"],
2060
+ ...icon == null ? [] : ["icon"],
2061
+ ..."iconSprite" in source ? ["iconSprite"] : [],
2062
+ ..."iconSpritePosition" in source ? ["iconSpritePosition"] : [],
2063
+ "inputs",
2064
+ "name",
2065
+ "outputs",
2066
+ "serviceId",
2067
+ "serviceName"
2068
+ ]);
2069
+ if (homepageUrl != null && typeof homepageUrl != "string" || icon != null && typeof icon != "string") return invalidResponse();
2070
+ return {
2071
+ ...source.inputSchema === void 0 ? {} : { inputSchema: jsonValue(source.inputSchema) },
2072
+ ...source.outputSchema === void 0 ? {} : { outputSchema: jsonValue(source.outputSchema) },
2073
+ actionId: string(source.actionId),
2074
+ ...source.operationType == null ? {} : { operationType: string(source.operationType) },
2075
+ authenticated: typeof source.authenticated == "boolean" ? source.authenticated : invalidResponse(),
2076
+ description: typeof source.description == "string" ? source.description : invalidResponse(),
2077
+ ...homepageUrl == null ? {} : { homepageUrl },
2078
+ ...icon == null ? {} : { icon },
2079
+ ...providerIconAppearance(source.iconSprite, source.iconSpritePosition),
2080
+ inputs: ports(source.inputs, inputPort),
2081
+ name: string(source.name),
2082
+ outputs: ports(source.outputs, port),
2083
+ serviceId: string(source.serviceId),
2084
+ serviceName: string(source.serviceName)
2085
+ };
2086
+ }
2087
+ function connectorAction(value) {
2088
+ const { defaultConnection, ...metadata } = record$1(value);
2089
+ const action = connectorActionMetadata(metadata);
2090
+ if (defaultConnection == null) return action;
2091
+ const preferred = connection(defaultConnection);
2092
+ if (preferred.serviceId != action.serviceId || preferred.status != "active") return invalidResponse();
2557
2093
  return {
2558
- resourceId,
2559
- kind: "trigger",
2560
- type,
2561
- name: string(source.name),
2562
- ...source.description == null ? {} : { description: source.description },
2563
- config: jsonValue(source.config),
2564
- inputs: jsonValue(source.inputs),
2565
- ...runtime == null ? {} : { runtime }
2094
+ ...action,
2095
+ defaultConnection: preferred
2566
2096
  };
2567
2097
  }
2568
- function decodePublicationResources(value) {
2098
+ function connectorProvider(value) {
2569
2099
  const source = record$1(value);
2570
- const scope = context(source);
2571
- if (!Array.isArray(source.resources)) return invalidResponse();
2100
+ const homepageUrl = source.homepageUrl;
2101
+ const icon = source.icon;
2102
+ if (source.noSetup !== void 0 && typeof source.noSetup != "boolean") return invalidResponse();
2103
+ exact(source, [
2104
+ ...Object.hasOwn(source, "noSetup") ? ["noSetup"] : [],
2105
+ "serviceId",
2106
+ "serviceName",
2107
+ ...homepageUrl == null ? [] : ["homepageUrl"],
2108
+ ...icon == null ? [] : ["icon"],
2109
+ ..."iconSprite" in source ? ["iconSprite"] : [],
2110
+ ..."iconSpritePosition" in source ? ["iconSpritePosition"] : []
2111
+ ]);
2112
+ if (homepageUrl != null && typeof homepageUrl != "string" || icon != null && typeof icon != "string") return invalidResponse();
2572
2113
  return {
2573
- ...scope,
2574
- resources: source.resources.map((item) => resource$7(item, scope))
2114
+ ...homepageUrl == null ? {} : { homepageUrl },
2115
+ ...icon == null ? {} : { icon },
2116
+ ...providerIconAppearance(source.iconSprite, source.iconSpritePosition),
2117
+ serviceId: string(source.serviceId),
2118
+ serviceName: string(source.serviceName),
2119
+ ...source.noSetup === void 0 ? {} : { noSetup: source.noSetup }
2575
2120
  };
2576
2121
  }
2577
- function decodePublicationResource(value) {
2578
- const source = record$1(value);
2579
- const scope = context(source);
2580
- return {
2581
- ...scope,
2582
- resource: resource$7(source.resource, scope)
2583
- };
2122
+ //#endregion
2123
+ //#region src/trigger/common/config.ts
2124
+ function triggerConfigValue(input, config) {
2125
+ return inputValue(config[input.handle], input.value);
2126
+ }
2127
+ /** Provider-specific controls consume values, never persistence wrappers. */
2128
+ function triggerConfigValues(inputs, config) {
2129
+ return Object.fromEntries(inputs.flatMap((input) => "handle" in input ? [[input.handle, triggerConfigValue(input, config) ?? null]] : []));
2584
2130
  }
2585
2131
  //#endregion
2586
- //#region src/control/common/providerIconSprite.ts
2587
- /** Optional artwork must never make an otherwise usable catalog unavailable. */
2588
- function providerIconAppearance(metadata, position) {
2589
- if (!metadata || typeof metadata != "object" || !position || typeof position != "object") return {};
2590
- const m = metadata;
2591
- const p = position;
2592
- if (typeof m.version != "string" || ![
2593
- m.pixelRatio,
2594
- m.iconSize,
2595
- m.width,
2596
- m.height
2597
- ].every((v) => Number.isInteger(v) && v > 0) || ![
2598
- m.bleed,
2599
- p.x,
2600
- p.y
2601
- ].every((v) => Number.isInteger(v) && v >= 0) || p.x + m.iconSize > m.width || p.y + m.iconSize > m.height) return {};
2132
+ //#region src/base/common/json.ts
2133
+ function hasJsonShape(root) {
2134
+ if (root === null || typeof root == "boolean" || typeof root == "string") return true;
2135
+ if (typeof root == "number") return Number.isFinite(root);
2136
+ if (typeof root != "object") return false;
2137
+ const ancestors = /* @__PURE__ */ new Set();
2138
+ const pending = [];
2139
+ let value = root;
2140
+ traversal: while (true) {
2141
+ let keys;
2142
+ let arrayLength;
2143
+ if (Array.isArray(value)) {
2144
+ arrayLength = value.length;
2145
+ keys = Reflect.ownKeys(value);
2146
+ if (keys.length != arrayLength + 1) return false;
2147
+ } else {
2148
+ const prototype = Reflect.getPrototypeOf(value);
2149
+ if (prototype != Object.prototype && prototype != null) return false;
2150
+ keys = Reflect.ownKeys(value);
2151
+ arrayLength = void 0;
2152
+ }
2153
+ ancestors.add(value);
2154
+ let index = 0;
2155
+ while (true) {
2156
+ if (index >= keys.length) {
2157
+ ancestors.delete(value);
2158
+ const parent = pending.pop();
2159
+ if (parent === void 0) return true;
2160
+ value = parent.value;
2161
+ keys = parent.keys;
2162
+ arrayLength = parent.arrayLength;
2163
+ index = parent.index;
2164
+ continue;
2165
+ }
2166
+ const key = keys[index++];
2167
+ if (arrayLength !== void 0) {
2168
+ if (key == "length") continue;
2169
+ if (typeof key != "string") return false;
2170
+ const arrayIndex = Number(key);
2171
+ if (!Number.isSafeInteger(arrayIndex) || arrayIndex < 0 || arrayIndex >= arrayLength || String(arrayIndex) != key) return false;
2172
+ } else if (typeof key != "string") return false;
2173
+ const descriptor = Reflect.getOwnPropertyDescriptor(value, key);
2174
+ if (descriptor?.enumerable != true || !Object.hasOwn(descriptor, "value")) return false;
2175
+ const child = descriptor.value;
2176
+ if (child === null || typeof child == "boolean" || typeof child == "string") continue;
2177
+ if (typeof child == "number") {
2178
+ if (!Number.isFinite(child)) return false;
2179
+ continue;
2180
+ }
2181
+ if (typeof child != "object" || ancestors.has(child)) return false;
2182
+ pending.push({
2183
+ value,
2184
+ keys,
2185
+ arrayLength,
2186
+ index
2187
+ });
2188
+ value = child;
2189
+ continue traversal;
2190
+ }
2191
+ }
2192
+ }
2193
+ function isJsonObject(value) {
2602
2194
  try {
2603
- for (const url of [m.lightUrl, m.darkUrl]) if (typeof url != "string" || ![
2604
- "https:",
2605
- "http:",
2606
- "data:"
2607
- ].includes(new URL(url).protocol)) return {};
2195
+ return value != null && typeof value == "object" && !Array.isArray(value) && hasJsonShape(value);
2608
2196
  } catch {
2609
- return {};
2197
+ return false;
2610
2198
  }
2611
- return {
2612
- iconSprite: m,
2613
- iconSpritePosition: {
2614
- x: p.x,
2615
- y: p.y
2199
+ }
2200
+ //#endregion
2201
+ //#region src/trigger/common/contract.ts
2202
+ var errorOutputs = [
2203
+ {
2204
+ handle: "workflow",
2205
+ nullable: false,
2206
+ jsonSchema: {
2207
+ type: "object",
2208
+ additionalProperties: false,
2209
+ required: [
2210
+ "flowId",
2211
+ "name",
2212
+ "revisionId",
2213
+ "publicationId"
2214
+ ],
2215
+ properties: {
2216
+ flowId: { type: "string" },
2217
+ name: { type: "string" },
2218
+ revisionId: { type: "string" },
2219
+ publicationId: { type: ["string", "null"] }
2220
+ }
2616
2221
  }
2617
- };
2222
+ },
2223
+ {
2224
+ handle: "execution",
2225
+ nullable: false,
2226
+ jsonSchema: {
2227
+ type: "object",
2228
+ additionalProperties: false,
2229
+ required: [
2230
+ "runId",
2231
+ "status",
2232
+ "startedAt",
2233
+ "finishedAt"
2234
+ ],
2235
+ properties: {
2236
+ runId: { type: "string" },
2237
+ status: { enum: ["failed", "indeterminate"] },
2238
+ startedAt: { type: ["string", "null"] },
2239
+ finishedAt: { type: "string" }
2240
+ }
2241
+ }
2242
+ },
2243
+ {
2244
+ handle: "error",
2245
+ nullable: false,
2246
+ jsonSchema: {
2247
+ type: "object",
2248
+ additionalProperties: false,
2249
+ required: ["code", "message"],
2250
+ properties: {
2251
+ code: { type: "string" },
2252
+ message: { type: "string" },
2253
+ nodeId: { type: "string" },
2254
+ jobId: { type: "string" },
2255
+ path: {
2256
+ type: "array",
2257
+ items: { type: "string" }
2258
+ }
2259
+ }
2260
+ }
2261
+ }
2262
+ ];
2263
+ var sampleErrorOutputs = {
2264
+ workflow: {
2265
+ flowId: "example-flow",
2266
+ name: "Example workflow",
2267
+ revisionId: "example-revision",
2268
+ publicationId: "example-publication"
2269
+ },
2270
+ execution: {
2271
+ runId: "example-run",
2272
+ status: "failed",
2273
+ startedAt: "2026-01-01T00:00:00.000Z",
2274
+ finishedAt: "2026-01-01T00:00:01.000Z"
2275
+ },
2276
+ error: {
2277
+ code: "node.failed",
2278
+ message: "Example failure",
2279
+ nodeId: "example-node",
2280
+ jobId: "example-job",
2281
+ path: []
2282
+ }
2283
+ };
2284
+ var webhookOutputs = [
2285
+ {
2286
+ handle: "headers",
2287
+ jsonSchema: {
2288
+ type: "object",
2289
+ additionalProperties: { type: "string" }
2290
+ },
2291
+ nullable: false
2292
+ },
2293
+ {
2294
+ handle: "query",
2295
+ jsonSchema: {
2296
+ type: "object",
2297
+ additionalProperties: {
2298
+ type: ["string", "array"],
2299
+ items: { type: "string" }
2300
+ }
2301
+ },
2302
+ nullable: false
2303
+ },
2304
+ {
2305
+ handle: "body",
2306
+ jsonSchema: {
2307
+ type: "object",
2308
+ additionalProperties: true
2309
+ },
2310
+ nullable: false
2311
+ },
2312
+ {
2313
+ handle: "webhookUrl",
2314
+ jsonSchema: { type: "string" },
2315
+ nullable: false
2316
+ }
2317
+ ];
2318
+ var cronOutputs = [{
2319
+ handle: "scheduledAt",
2320
+ jsonSchema: {
2321
+ type: "string",
2322
+ format: "date-time"
2323
+ },
2324
+ nullable: false
2325
+ }];
2326
+ function triggerOutputDefinitions(trigger) {
2327
+ switch (trigger.kind) {
2328
+ case "error": return errorOutputs;
2329
+ case "manual": return [];
2330
+ case "cron": return cronOutputs;
2331
+ case "poll":
2332
+ case "integration": return trigger.definition.outputs;
2333
+ case "webhook": return webhookOutputs.filter((port) => port.handle !== "body" || webhookSupportsBody(trigger.method)).map((port) => port.handle === "body" ? Object.assign({}, port, { jsonSchema: {
2334
+ type: "object",
2335
+ additionalProperties: false,
2336
+ properties: Object.fromEntries(trigger.bodyFields.map((field) => [field.handle, field.jsonSchema])),
2337
+ required: trigger.bodyFields.filter((field) => !field.nullable && !Object.hasOwn(field, "value")).map((field) => field.handle)
2338
+ } }) : port);
2339
+ }
2340
+ }
2341
+ function triggerOutputPorts(trigger) {
2342
+ return Object.fromEntries(triggerOutputDefinitions(trigger).map(({ handle, ...port }) => [handle, port]));
2618
2343
  }
2619
- new TextEncoder();
2620
2344
  //#endregion
2621
- //#region src/control/common/providerAccess.ts
2622
- var sourceSchema = discriminatedUnion("kind", [strictObject({ kind: literal("admin-delegation") }), strictObject({
2623
- kind: literal("policy"),
2624
- ruleId: string$1().min(1).nullable()
2625
- })]);
2626
- function parseProviderAccessSource(value) {
2627
- return sourceSchema.parse(value);
2345
+ //#region src/flow/common/sourceField.ts
2346
+ /** Only explicitly declared, first-level object properties are selectable. */
2347
+ function sourceFields(output) {
2348
+ const schema = schemaObject(output.jsonSchema);
2349
+ if (schema == null) return [];
2350
+ const properties = schemaObject(schema.properties ?? false);
2351
+ const types = Array.isArray(schema.type) ? schema.type : [schema.type];
2352
+ if (properties == null || schema.type !== void 0 && !types.includes("object")) return [];
2353
+ const required = Array.isArray(schema.required) ? schema.required : [];
2354
+ const missingParent = output.nullable || types.some((type) => type !== "object");
2355
+ return Object.entries(properties).map(([field, jsonSchema]) => {
2356
+ const description = schemaObject(jsonSchema)?.description;
2357
+ return {
2358
+ field,
2359
+ port: {
2360
+ ...typeof description == "string" ? { description } : {},
2361
+ jsonSchema,
2362
+ nullable: missingParent || !required.includes(field)
2363
+ }
2364
+ };
2365
+ });
2366
+ }
2367
+ function sourcePort(output, field) {
2368
+ return field === void 0 ? output : sourceFields(output).find((candidate) => candidate.field === field)?.port;
2369
+ }
2370
+ /** Present a selected first-level field as a compact path from its output. */
2371
+ function sourceOutputLabel(source) {
2372
+ return source.field === void 0 ? source.output : `${source.output} / ${source.field}`;
2628
2373
  }
2629
2374
  //#endregion
2630
- //#region src/control/common/connectorDecoders.ts
2631
- function accessPermissions(value) {
2632
- const source = record$1(value);
2633
- exact(source, [
2634
- "actionIds",
2635
- "allActions",
2636
- "triggerIds",
2637
- "allTriggers",
2638
- "configured",
2639
- "proxy"
2640
- ]);
2641
- if (!Array.isArray(source.actionIds)) return invalidResponse("permissions.actionIds: expected an array.");
2642
- if (!Array.isArray(source.triggerIds)) return invalidResponse("permissions.triggerIds: expected an array.");
2643
- if (typeof source.allActions != "boolean") return invalidResponse("permissions.allActions: expected a boolean.");
2644
- if (typeof source.allTriggers != "boolean") return invalidResponse("permissions.allTriggers: expected a boolean.");
2645
- if (typeof source.configured != "boolean") return invalidResponse("permissions.configured: expected a boolean.");
2646
- if (typeof source.proxy != "boolean") return invalidResponse("permissions.proxy: expected a boolean.");
2647
- const actionIds = source.actionIds.map(string);
2648
- const triggerIds = source.triggerIds.map(string);
2649
- if (new Set(actionIds).size != actionIds.length) return invalidResponse("permissions.actionIds: duplicate IDs.");
2650
- if (source.allActions && actionIds.length != 0) return invalidResponse("permissions.actionIds: must be empty when allActions is true.");
2651
- if (new Set(triggerIds).size != triggerIds.length) return invalidResponse("permissions.triggerIds: duplicate IDs.");
2652
- if (source.allTriggers && triggerIds.length != 0) return invalidResponse("permissions.triggerIds: must be empty when allTriggers is true.");
2653
- if (source.proxy && (!source.allActions || !source.allTriggers || source.configured)) return invalidResponse("permissions.proxy: requires allActions=true, allTriggers=true and configured=false.");
2654
- return {
2655
- actionIds,
2656
- triggerIds,
2657
- allTriggers: source.allTriggers,
2658
- allActions: source.allActions,
2659
- configured: source.configured,
2660
- proxy: source.proxy
2661
- };
2375
+ //#region src/flow/common/graph.ts
2376
+ function isResolutionNode(node) {
2377
+ return node?.kind == "approval" || node?.kind == "wait";
2662
2378
  }
2663
- function accessBinding(value, candidate) {
2664
- const source = record$1(value);
2665
- const policyRevision = source.policyRevision;
2666
- const status = source.status;
2667
- const isDefault = source.isDefault;
2668
- const legacy = Object.hasOwn(source, "displayName") && !Object.hasOwn(source, "connectionDisplayName");
2669
- const permissions = candidate && Object.hasOwn(source, "permissions") ? accessPermissions(source.permissions) : void 0;
2670
- const permissionGroupName = source.permissionGroupName;
2671
- exact(source, [
2672
- "accessBindingId",
2673
- "connectionId",
2674
- "source",
2675
- legacy ? "displayName" : "connectionDisplayName",
2676
- ...candidate && Object.hasOwn(source, "isDefault") ? ["isDefault"] : [],
2677
- ...candidate && permissions != null ? ["permissions"] : [],
2678
- ...Object.hasOwn(source, "permissionGroupName") ? ["permissionGroupName"] : [],
2679
- ...policyRevision == null ? [] : ["policyRevision"],
2680
- "providerId",
2681
- ...candidate ? [] : ["status"]
2682
- ]);
2683
- if (policyRevision != null && typeof policyRevision != "string") return invalidResponse("policyRevision: expected a string.");
2684
- if (candidate && isDefault !== void 0 && typeof isDefault != "boolean") return invalidResponse("isDefault: expected a boolean.");
2685
- if (permissionGroupName !== void 0 && permissionGroupName !== null && typeof permissionGroupName != "string") return invalidResponse("permissionGroupName: expected a string or null.");
2686
- if (!candidate && status != "active" && status != "forbidden" && status != "invalid" && status != "missing") return invalidResponse();
2687
- let bindingSource;
2688
- try {
2689
- bindingSource = parseProviderAccessSource(source.source);
2690
- } catch {
2691
- return invalidResponse("source: expected { kind: 'admin-delegation' } or { kind: 'policy', ruleId: string | null }.");
2379
+ function nodeInputPorts(node) {
2380
+ switch (node.kind) {
2381
+ case "condition": return conditionInputPorts(node);
2382
+ case "value": return {};
2383
+ case "task": return portsByHandle([...node.task.inputs, ...node.additionalInputs ?? []]);
2384
+ case "approval":
2385
+ case "wait": return portsByHandle(node.inputDefinitions);
2386
+ case "cron":
2387
+ case "integration":
2388
+ case "poll":
2389
+ case "error":
2390
+ case "manual":
2391
+ case "webhook": return {};
2692
2392
  }
2693
- return {
2694
- accessBindingId: string(source.accessBindingId),
2695
- connectionId: string(source.connectionId),
2696
- source: bindingSource,
2697
- connectionDisplayName: string(legacy ? source.displayName : source.connectionDisplayName),
2698
- ...candidate && typeof isDefault == "boolean" ? { isDefault } : {},
2699
- ...permissions == null ? {} : { permissions },
2700
- ...permissionGroupName === void 0 ? {} : { permissionGroupName },
2701
- ...policyRevision == null ? {} : { policyRevision },
2702
- providerId: string(source.providerId),
2703
- ...candidate ? {} : { status }
2704
- };
2705
2393
  }
2706
- function accessMode(value) {
2707
- if (value != "implicit" && value != "selectable") return invalidResponse("mode: expected implicit or selectable.");
2708
- return value;
2394
+ function resolutionActions(node) {
2395
+ return node.kind == "wait" ? ["continue"] : ["approve", "reject"];
2709
2396
  }
2710
- function connectorAccess$7(value) {
2711
- const source = record$1(value);
2712
- exact(source, [
2713
- "accessRevision",
2714
- "bindings",
2715
- "mode",
2716
- "sharedAccessDigest",
2717
- ..."providerIds" in source ? ["providerIds"] : [],
2718
- ..."discardedBindingCount" in source ? ["discardedBindingCount"] : [],
2719
- "version"
2720
- ]);
2721
- const accessRevision = integer(source.accessRevision);
2722
- if (source.version != 1 || accessRevision < 0 || !Array.isArray(source.bindings)) return invalidResponse();
2723
- if ("providerIds" in source && !Array.isArray(source.providerIds)) return invalidResponse();
2724
- const providerIds = source.providerIds == null ? void 0 : source.providerIds.map((id) => string(id));
2725
- if (providerIds != null && new Set(providerIds).size != providerIds.length) return invalidResponse();
2726
- let discardedBindingCount = source.discardedBindingCount == null ? 0 : integer(source.discardedBindingCount);
2727
- if (discardedBindingCount < 0) return invalidResponse();
2728
- const bindings = [];
2729
- for (const entry of source.bindings) try {
2730
- bindings.push(accessBinding(entry, false));
2731
- } catch (error) {
2732
- if (!(error instanceof ApiError) || error.code != "response.invalid") throw error;
2733
- if (entry != null && typeof entry == "object" && !Array.isArray(entry) && typeof entry.accessBindingId == "string" && entry.accessBindingId.length > 0 && typeof entry.providerId == "string" && entry.providerId.length > 0) bindings.push({
2734
- accessBindingId: entry.accessBindingId,
2735
- providerId: entry.providerId,
2736
- connectionId: null,
2737
- source: null,
2738
- status: "invalid",
2739
- connectionDisplayName: typeof entry.connectionDisplayName == "string" && entry.connectionDisplayName.length > 0 ? entry.connectionDisplayName : typeof entry.displayName == "string" && entry.displayName.length > 0 ? entry.displayName : entry.providerId,
2740
- permissionGroupName: typeof entry.permissionGroupName == "string" ? entry.permissionGroupName : null
2741
- });
2742
- else discardedBindingCount++;
2397
+ var objectPort = (properties) => ({
2398
+ nullable: false,
2399
+ jsonSchema: {
2400
+ type: "object",
2401
+ properties,
2402
+ required: Object.keys(properties),
2403
+ additionalProperties: false
2743
2404
  }
2744
- if (new Set(bindings.map((binding) => binding.accessBindingId)).size != bindings.length) return invalidResponse();
2405
+ });
2406
+ function resolutionOutputPorts(node) {
2407
+ const actions = resolutionActions(node);
2408
+ const inputs = {
2409
+ type: "object",
2410
+ properties: Object.fromEntries(node.inputDefinitions.map((port) => [port.handle, {}])),
2411
+ required: node.inputDefinitions.map((port) => port.handle),
2412
+ additionalProperties: false
2413
+ };
2745
2414
  return {
2746
- accessRevision,
2747
- ...discardedBindingCount == 0 ? {} : { discardedBindingCount },
2748
- ...providerIds == null ? {} : { providerIds },
2749
- bindings,
2750
- mode: accessMode(source.mode),
2751
- sharedAccessDigest: string(source.sharedAccessDigest),
2752
- version: 1
2415
+ pending: objectPort({
2416
+ inputs,
2417
+ prompt: { type: "string" },
2418
+ ...Object.fromEntries(actions.map((action) => [`${action}Url`, { type: "string" }])),
2419
+ expiresAt: { type: "string" }
2420
+ }),
2421
+ ...Object.fromEntries(actions.map((action) => [action, objectPort({
2422
+ inputs,
2423
+ action: { const: action },
2424
+ resolvedAt: { type: "string" },
2425
+ comment: { type: ["string", "null"] }
2426
+ })]))
2753
2427
  };
2754
2428
  }
2755
- function accessGrants(value) {
2756
- if (!Array.isArray(value)) return invalidResponse();
2757
- const bindings = value.map((candidate) => {
2758
- const entry = record$1(candidate);
2759
- exact(entry, [
2760
- "accessBindingId",
2761
- "connectionId",
2762
- "providerId",
2763
- "source",
2764
- "connectionDisplayName",
2765
- ..."permissionGroupName" in entry ? ["permissionGroupName"] : []
2766
- ]);
2767
- let identity;
2768
- try {
2769
- identity = parseProviderAccessSource(entry.source);
2770
- } catch {
2771
- return invalidResponse();
2429
+ function nodeOutputPorts(node) {
2430
+ switch (node.kind) {
2431
+ case "condition": return {};
2432
+ case "value": return portsByHandle(node.values);
2433
+ case "task": return portsByHandle(node.task.outputs);
2434
+ case "approval":
2435
+ case "wait": return resolutionOutputPorts(node);
2436
+ case "cron":
2437
+ case "integration":
2438
+ case "poll":
2439
+ case "error":
2440
+ case "manual":
2441
+ case "webhook": return triggerOutputPorts(node);
2442
+ }
2443
+ }
2444
+ function nodeOutputDescription(graph, nodeId, output) {
2445
+ const node = graph.nodes[nodeId];
2446
+ return node == null ? void 0 : nodeOutputPorts(node)[output]?.description;
2447
+ }
2448
+ function graphOrder(graph) {
2449
+ const pending = new Map(Object.keys(graph.nodes).map((id) => [id, /* @__PURE__ */ new Set()]));
2450
+ const children = /* @__PURE__ */ new Map();
2451
+ for (const edge of graph.edges) {
2452
+ if (!pending.has(edge.source) || !pending.has(edge.target)) continue;
2453
+ pending.get(edge.target)?.add(edge.source);
2454
+ const targets = children.get(edge.source) ?? /* @__PURE__ */ new Set();
2455
+ targets.add(edge.target);
2456
+ children.set(edge.source, targets);
2457
+ }
2458
+ const ready = [...pending].filter(([, parents]) => parents.size == 0).map(([id]) => id).toSorted();
2459
+ for (let index = 0; index < ready.length; index++) {
2460
+ const id = ready[index];
2461
+ pending.delete(id);
2462
+ for (const child of children.get(id) ?? []) {
2463
+ const parents = pending.get(child);
2464
+ parents?.delete(id);
2465
+ if (parents?.size == 0) ready.push(child);
2772
2466
  }
2773
- if (entry.permissionGroupName != null && typeof entry.permissionGroupName != "string") return invalidResponse();
2774
- return {
2775
- accessBindingId: string(entry.accessBindingId),
2776
- connectionId: string(entry.connectionId),
2777
- providerId: string(entry.providerId),
2778
- source: identity,
2779
- connectionDisplayName: string(entry.connectionDisplayName),
2780
- ..."permissionGroupName" in entry ? { permissionGroupName: entry.permissionGroupName } : {}
2781
- };
2782
- });
2783
- if (new Set(bindings.map((binding) => binding.accessBindingId)).size != bindings.length) return invalidResponse();
2784
- return bindings;
2467
+ }
2468
+ return [...ready, ...[...pending.keys()].toSorted()];
2785
2469
  }
2786
- function connectorAccessSnapshot(value) {
2787
- const source = record$1(value);
2788
- exact(source, [
2789
- "mode",
2790
- "sharedAccessDigest",
2791
- "sharedBindings",
2792
- "selectedBindings",
2793
- "version"
2794
- ]);
2795
- if (source.version != 2) return invalidResponse();
2796
- const mode = accessMode(source.mode);
2797
- const sharedBindings = accessGrants(source.sharedBindings);
2798
- const selectedBindings = accessGrants(source.selectedBindings);
2799
- if (mode == "implicit" && (sharedBindings.length > 0 || selectedBindings.length > 0)) return invalidResponse();
2800
- return {
2801
- mode,
2802
- sharedAccessDigest: string(source.sharedAccessDigest),
2803
- sharedBindings,
2804
- selectedBindings,
2805
- version: 2
2806
- };
2470
+ var pathsByGraph = /* @__PURE__ */ new WeakMap();
2471
+ function routeCovers(route, target) {
2472
+ return Object.entries(route).every(([key, value]) => target[key] == value);
2807
2473
  }
2808
- function connectorAccessCandidates(value, providerId) {
2809
- const source = record$1(value);
2810
- exact(source, [
2811
- "candidates",
2812
- "mode",
2813
- "providerId",
2814
- "version"
2815
- ]);
2816
- if (source.version != 1) return invalidResponse("version: expected 1.");
2817
- if (string(source.providerId) != providerId) return invalidResponse("providerId: does not match the requested provider.");
2818
- if (!Array.isArray(source.candidates)) return invalidResponse("candidates: expected an array.");
2819
- const candidates = source.candidates.map((candidate) => accessBinding(candidate, true));
2820
- if (candidates.some((candidate) => candidate.providerId != providerId)) return invalidResponse("candidates[].providerId: does not match the requested provider.");
2821
- if (new Set(candidates.map((candidate) => candidate.accessBindingId)).size != candidates.length) return invalidResponse("candidates[].accessBindingId: duplicate IDs.");
2822
- return {
2823
- candidates,
2824
- mode: accessMode(source.mode),
2825
- providerId,
2826
- version: 1
2827
- };
2474
+ function routesCompatible(left, right) {
2475
+ return Object.entries(left).every(([key, value]) => right[key] == null || right[key] == value);
2828
2476
  }
2829
- function connectorAccessCandidatesBatch(value, providerIds) {
2830
- const source = record$1(value);
2831
- exact(source, ["results", "version"]);
2832
- if (source.version != 1) return invalidResponse("version: expected 1.");
2833
- if (!Array.isArray(source.results)) return invalidResponse("results: expected an array.");
2834
- const remaining = new Set(providerIds);
2835
- const results = source.results.map((entry) => {
2836
- const item = record$1(entry);
2837
- const providerId = string(item.providerId);
2838
- if (!remaining.delete(providerId)) return invalidResponse("results[].providerId: duplicate or unrequested provider.");
2839
- if (!Object.hasOwn(item, "error")) return connectorAccessCandidates(item, providerId);
2840
- exact(item, ["providerId", "error"]);
2841
- const error = record$1(item.error);
2842
- exact(error, ["code", "message"]);
2843
- return {
2844
- providerId,
2845
- error: {
2846
- code: string(error.code),
2847
- message: string(error.message)
2848
- }
2849
- };
2850
- });
2851
- if (remaining.size != 0) return invalidResponse("results: missing requested providers.");
2852
- return {
2853
- results,
2854
- version: 1
2855
- };
2477
+ function resolutionOutputKey(nodeId, output) {
2478
+ return JSON.stringify([nodeId, output]);
2856
2479
  }
2857
- function connection(value) {
2858
- const source = record$1(value);
2859
- exact(source, [
2860
- ...Object.hasOwn(source, "providerAccountId") ? ["providerAccountId"] : [],
2861
- ...Object.hasOwn(source, "alias") ? ["alias"] : [],
2862
- ...Object.hasOwn(source, "builtInAccount") ? ["builtInAccount"] : [],
2863
- "connectionId",
2864
- "displayName",
2865
- "isDefault",
2866
- "serviceId",
2867
- "status"
2868
- ]);
2869
- if (source.builtInAccount !== void 0 && typeof source.builtInAccount != "boolean") return invalidResponse();
2870
- const status = source.status;
2871
- if (status != "active" && status != "disconnected" && status != "error" && status != "reauth_required") return invalidResponse();
2872
- if (typeof source.isDefault != "boolean") return invalidResponse();
2873
- return {
2874
- ...source.providerAccountId === void 0 ? {} : { providerAccountId: string(source.providerAccountId) },
2875
- ...source.alias === void 0 ? {} : { alias: string(source.alias) },
2876
- ...source.builtInAccount === void 0 ? {} : { builtInAccount: source.builtInAccount },
2877
- connectionId: string(source.connectionId),
2878
- displayName: string(source.displayName),
2879
- isDefault: source.isDefault,
2880
- serviceId: string(source.serviceId),
2881
- status
2480
+ function graphPaths(graph) {
2481
+ const cached = pathsByGraph.get(graph);
2482
+ if (cached != null) return cached;
2483
+ const paths = /* @__PURE__ */ new Map();
2484
+ const ancestors = /* @__PURE__ */ new Map();
2485
+ const resolutionOutputs = /* @__PURE__ */ new Map();
2486
+ const incoming = /* @__PURE__ */ new Map();
2487
+ for (const edge of graph.edges) {
2488
+ const edges = incoming.get(edge.target) ?? [];
2489
+ edges.push(edge);
2490
+ incoming.set(edge.target, edges);
2491
+ }
2492
+ const order = graphOrder(graph);
2493
+ let changed = true;
2494
+ while (changed) {
2495
+ changed = false;
2496
+ for (const id of order) {
2497
+ const node = graph.nodes[id];
2498
+ const edges = incoming.get(id) ?? [];
2499
+ const parents = /* @__PURE__ */ new Set();
2500
+ const resolutions = /* @__PURE__ */ new Set();
2501
+ const routes = [];
2502
+ for (const edge of edges) {
2503
+ parents.add(edge.source);
2504
+ for (const output of resolutionOutputs.get(edge.source) ?? []) resolutions.add(output);
2505
+ if (isResolutionNode(graph.nodes[edge.source]) && edge.sourceHandle != null) resolutions.add(resolutionOutputKey(edge.source, edge.sourceHandle));
2506
+ for (const parent of ancestors.get(edge.source) ?? []) parents.add(parent);
2507
+ for (const route of paths.get(edge.source) ?? []) {
2508
+ const next = edge.sourceHandle == null || isResolutionNode(graph.nodes[edge.source]) && edge.sourceHandle == "pending" ? route : {
2509
+ ...route,
2510
+ [edge.source]: graph.nodes[edge.source]?.kind == "condition" && graph.nodes[edge.source].matchMode == "all" && edge.sourceHandle != "otherwise" ? "$matched" : edge.sourceHandle
2511
+ };
2512
+ if (routes.some((known) => routeCovers(known, next))) continue;
2513
+ for (let index = routes.length - 1; index >= 0; index--) if (routeCovers(next, routes[index])) routes.splice(index, 1);
2514
+ routes.push(next);
2515
+ }
2516
+ }
2517
+ const nextRoutes = edges.length == 0 ? "inputs" in node ? [{}] : [{ $trigger: id }] : routes;
2518
+ const previous = paths.get(id) ?? [];
2519
+ if (parents.size != (ancestors.get(id)?.size ?? 0) || resolutions.size != (resolutionOutputs.get(id)?.size ?? 0) || nextRoutes.length != previous.length || nextRoutes.some((route) => !previous.some((known) => routeCovers(known, route) && routeCovers(route, known)))) changed = true;
2520
+ ancestors.set(id, parents);
2521
+ resolutionOutputs.set(id, resolutions);
2522
+ paths.set(id, nextRoutes);
2523
+ }
2524
+ }
2525
+ const analysis = {
2526
+ ancestors,
2527
+ paths,
2528
+ resolutionOutputs
2882
2529
  };
2530
+ pathsByGraph.set(graph, analysis);
2531
+ return analysis;
2883
2532
  }
2884
- function port(value, input = false) {
2885
- const source = record$1(value);
2886
- const description = source.description;
2887
- const hasValue = input && Object.hasOwn(source, "value");
2888
- exact(source, [
2889
- "jsonSchema",
2890
- "nullable",
2891
- ...description == null ? [] : ["description"],
2892
- ...hasValue ? ["value"] : []
2893
- ]);
2894
- if (description != null && typeof description != "string") return invalidResponse();
2895
- if (typeof source.nullable != "boolean") return invalidResponse();
2896
- return {
2897
- ...description == null ? {} : { description },
2898
- jsonSchema: jsonValue(source.jsonSchema),
2899
- nullable: source.nullable,
2900
- ...hasValue ? { value: jsonValue(source.value) } : {}
2901
- };
2533
+ function sourcePaths(graph, paths, source) {
2534
+ if (source.kind != "node") return [{}];
2535
+ const node = graph.nodes[source.nodeId];
2536
+ const routes = paths.get(source.nodeId) ?? [];
2537
+ return node?.kind == "condition" || isResolutionNode(node) && source.output != "pending" ? routes.map((route) => ({
2538
+ ...route,
2539
+ [source.nodeId]: source.output
2540
+ })) : routes;
2902
2541
  }
2903
- function inputPort(value) {
2904
- return port(value, true);
2542
+ function mappingAvailable(graph, target, mapping, analysis) {
2543
+ if (mapping.kind != "sources") return true;
2544
+ const { ancestors, paths } = analysis;
2545
+ if (target != null && mapping.sources.some((source) => source.kind == "node" && !ancestors.get(target)?.has(source.nodeId))) return false;
2546
+ if (target != null && mapping.sources.some((source) => source.kind == "node" && isResolutionNode(graph.nodes[source.nodeId]) && !analysis.resolutionOutputs.get(target)?.has(resolutionOutputKey(source.nodeId, source.output)))) return false;
2547
+ const sources = mapping.sources.map((source) => sourcePaths(graph, paths, source));
2548
+ const targetPaths = target == null ? [{}] : paths.get(target) ?? [];
2549
+ for (const [index, routes] of sources.entries()) for (const [offset, other] of sources.slice(index + 1).entries()) {
2550
+ const leftSource = mapping.sources[index];
2551
+ const rightSource = mapping.sources[index + offset + 1];
2552
+ if (target != null && leftSource.kind == "node" && rightSource.kind == "node" && leftSource.nodeId != rightSource.nodeId && !ancestors.get(leftSource.nodeId)?.has(rightSource.nodeId) && !ancestors.get(rightSource.nodeId)?.has(leftSource.nodeId)) continue;
2553
+ for (const left of routes) for (const targetRoute of targetPaths) {
2554
+ if (!routesCompatible(left, targetRoute)) continue;
2555
+ const path = {
2556
+ ...targetRoute,
2557
+ ...left
2558
+ };
2559
+ if (other.some((right) => routesCompatible(right, path))) return false;
2560
+ }
2561
+ }
2562
+ return true;
2905
2563
  }
2906
- function ports(value, decode) {
2907
- return Object.fromEntries(Object.entries(record$1(value)).map(([handle, candidate]) => [handle, decode(candidate)]));
2564
+ function sourceCompatibility(source, input) {
2565
+ const result = comparePorts(source, input);
2566
+ if (result.kind == "compatible") return { kind: "available" };
2567
+ return result.kind == "incompatible" ? {
2568
+ kind: "schema",
2569
+ mismatch: result.mismatch
2570
+ } : { kind: "schema-error" };
2908
2571
  }
2909
- function connectorActionMetadata(value) {
2910
- const source = record$1(value);
2911
- const homepageUrl = source.homepageUrl;
2912
- const icon = source.icon;
2913
- exact(source, [
2914
- "actionId",
2915
- ...Object.hasOwn(source, "operationType") ? ["operationType"] : [],
2916
- ...Object.hasOwn(source, "inputSchema") ? ["inputSchema"] : [],
2917
- ...Object.hasOwn(source, "outputSchema") ? ["outputSchema"] : [],
2918
- "authenticated",
2919
- "description",
2920
- ...homepageUrl == null ? [] : ["homepageUrl"],
2921
- ...icon == null ? [] : ["icon"],
2922
- ..."iconSprite" in source ? ["iconSprite"] : [],
2923
- ..."iconSpritePosition" in source ? ["iconSpritePosition"] : [],
2924
- "inputs",
2925
- "name",
2926
- "outputs",
2927
- "serviceId",
2928
- "serviceName"
2929
- ]);
2930
- if (homepageUrl != null && typeof homepageUrl != "string" || icon != null && typeof icon != "string") return invalidResponse();
2931
- return {
2932
- ...source.inputSchema === void 0 ? {} : { inputSchema: jsonValue(source.inputSchema) },
2933
- ...source.outputSchema === void 0 ? {} : { outputSchema: jsonValue(source.outputSchema) },
2934
- actionId: string(source.actionId),
2935
- ...source.operationType == null ? {} : { operationType: string(source.operationType) },
2936
- authenticated: typeof source.authenticated == "boolean" ? source.authenticated : invalidResponse(),
2937
- description: typeof source.description == "string" ? source.description : invalidResponse(),
2938
- ...homepageUrl == null ? {} : { homepageUrl },
2939
- ...icon == null ? {} : { icon },
2940
- ...providerIconAppearance(source.iconSprite, source.iconSpritePosition),
2941
- inputs: ports(source.inputs, inputPort),
2942
- name: string(source.name),
2943
- outputs: ports(source.outputs, port),
2944
- serviceId: string(source.serviceId),
2945
- serviceName: string(source.serviceName)
2946
- };
2572
+ /** Check one saved binding without enumerating candidate ports. */
2573
+ function checkInputSource(graph, target, handle, source) {
2574
+ const node = graph.nodes[source.nodeId];
2575
+ const targetNode = graph.nodes[target];
2576
+ if (node == null) return { kind: "source-missing" };
2577
+ if (targetNode == null) return { kind: "not-ready" };
2578
+ const output = nodeOutputPorts(node)[source.output];
2579
+ const input = nodeInputPorts(targetNode)[handle];
2580
+ if (output == null) return { kind: "output-missing" };
2581
+ if (input == null) return { kind: "not-ready" };
2582
+ const analysis = graphPaths(graph);
2583
+ if (analysis.ancestors.get(target)?.has(source.nodeId) !== true) return { kind: "not-ready" };
2584
+ if (isResolutionNode(node) && !analysis.resolutionOutputs.get(target)?.has(resolutionOutputKey(source.nodeId, source.output))) return { kind: "not-ready" };
2585
+ const selected = sourcePort(output, source.field);
2586
+ if (selected == null) return { kind: "field-missing" };
2587
+ return sourceCompatibility(selected, input);
2947
2588
  }
2948
- function connectorAction(value) {
2949
- const { defaultConnection, ...metadata } = record$1(value);
2950
- const action = connectorActionMetadata(metadata);
2951
- if (defaultConnection == null) return action;
2952
- const preferred = connection(defaultConnection);
2953
- if (preferred.serviceId != action.serviceId || preferred.status != "active") return invalidResponse();
2589
+ function checkInputSources(graph, target, handle, sources) {
2590
+ const checks = sources.map((source) => checkInputSource(graph, target, handle, source));
2954
2591
  return {
2955
- ...action,
2956
- defaultConnection: preferred
2592
+ conflict: checks.length > 1 && checks.every((check) => check.kind == "available") && !mappingAvailable(graph, target, {
2593
+ kind: "sources",
2594
+ sources: sources.map((source) => ({
2595
+ kind: "node",
2596
+ ...source
2597
+ }))
2598
+ }, graphPaths(graph)),
2599
+ sources: checks
2957
2600
  };
2958
2601
  }
2959
- function connectorProvider(value) {
2960
- const source = record$1(value);
2961
- const homepageUrl = source.homepageUrl;
2962
- const icon = source.icon;
2963
- if (source.noSetup !== void 0 && typeof source.noSetup != "boolean") return invalidResponse();
2964
- exact(source, [
2965
- ...Object.hasOwn(source, "noSetup") ? ["noSetup"] : [],
2966
- "serviceId",
2967
- "serviceName",
2968
- ...homepageUrl == null ? [] : ["homepageUrl"],
2969
- ...icon == null ? [] : ["icon"],
2970
- ..."iconSprite" in source ? ["iconSprite"] : [],
2971
- ..."iconSpritePosition" in source ? ["iconSpritePosition"] : []
2972
- ]);
2973
- if (homepageUrl != null && typeof homepageUrl != "string" || icon != null && typeof icon != "string") return invalidResponse();
2974
- return {
2975
- ...homepageUrl == null ? {} : { homepageUrl },
2976
- ...icon == null ? {} : { icon },
2977
- ...providerIconAppearance(source.iconSprite, source.iconSpritePosition),
2978
- serviceId: string(source.serviceId),
2979
- serviceName: string(source.serviceName),
2980
- ...source.noSetup === void 0 ? {} : { noSetup: source.noSetup }
2981
- };
2602
+ /** Enumerate structurally available outputs while retaining their compatibility with one input. */
2603
+ function inputSourceCandidates(graph, target, handle) {
2604
+ const targetNode = graph.nodes[target];
2605
+ const input = targetNode == null ? void 0 : nodeInputPorts(targetNode)[handle];
2606
+ if (input == null) return {};
2607
+ const analysis = graphPaths(graph);
2608
+ return Object.fromEntries([...analysis.ancestors.get(target) ?? []].flatMap((nodeId) => {
2609
+ const node = graph.nodes[nodeId];
2610
+ if (node == null) return [];
2611
+ const outputs = Object.entries(nodeOutputPorts(node)).flatMap(([output, definition]) => {
2612
+ if (!mappingAvailable(graph, target, {
2613
+ kind: "sources",
2614
+ sources: [{
2615
+ kind: "node",
2616
+ nodeId,
2617
+ output
2618
+ }]
2619
+ }, analysis)) return [];
2620
+ const check = sourceCompatibility(definition, input);
2621
+ const fields = sourceFields(definition).map(({ field, port }) => Object.assign({
2622
+ output,
2623
+ field,
2624
+ check: sourceCompatibility(port, input)
2625
+ }, port.description == null ? {} : { description: port.description }));
2626
+ return [{
2627
+ ...definition.description == null ? {} : { description: definition.description },
2628
+ output,
2629
+ check,
2630
+ ...fields.length > 0 ? { fields } : {}
2631
+ }];
2632
+ });
2633
+ return outputs.length == 0 ? [] : [[nodeId, outputs]];
2634
+ }));
2982
2635
  }
2983
2636
  //#endregion
2984
2637
  //#region src/control/common/eventSources.ts
@@ -3403,142 +3056,6 @@ function variableReferences(input) {
3403
3056
  };
3404
3057
  }
3405
3058
  //#endregion
3406
- //#region src/control/common/publicationDecoders.ts
3407
- function publication$7(value) {
3408
- const source = record$1(value);
3409
- const liveEnd = source.liveEnd == null ? void 0 : record$1(source.liveEnd);
3410
- if (liveEnd != null && typeof liveEnd.enabled != "boolean") return invalidResponse();
3411
- const operation = source.operation;
3412
- const sourcePublicationId = source.sourcePublicationId;
3413
- if (source.version != 1) return invalidResponse();
3414
- if (operation != "publish" && operation != "rollback") return invalidResponse();
3415
- if (sourcePublicationId != null && typeof sourcePublicationId != "string") return invalidResponse();
3416
- return {
3417
- ...liveEnd == null ? {} : { liveEnd: {
3418
- enabled: liveEnd.enabled,
3419
- endedAt: string(liveEnd.endedAt)
3420
- } },
3421
- actorId: string(source.actorId),
3422
- closureDigest: string(source.closureDigest),
3423
- createdAt: string(source.createdAt),
3424
- engineContract: string(source.engineContract),
3425
- flowId: string(source.flowId),
3426
- modelVersion: integer(source.modelVersion),
3427
- operation,
3428
- publicationId: string(source.publicationId),
3429
- sharedAccessDigest: string(source.sharedAccessDigest),
3430
- revisionDigest: string(source.revisionDigest),
3431
- revisionId: string(source.revisionId),
3432
- ...sourcePublicationId == null ? {} : { sourcePublicationId },
3433
- version: 1
3434
- };
3435
- }
3436
- function publishOperation(value) {
3437
- const source = record$1(value);
3438
- const status = source.status;
3439
- const common = {
3440
- createdAt: string(source.createdAt),
3441
- flowId: string(source.flowId),
3442
- operationId: string(source.operationId),
3443
- revisionId: string(source.revisionId),
3444
- updatedAt: string(source.updatedAt),
3445
- version: 1
3446
- };
3447
- if (source.version != 1) return invalidResponse();
3448
- switch (status) {
3449
- case "pending":
3450
- exact(source, [
3451
- "createdAt",
3452
- "flowId",
3453
- "operationId",
3454
- "revisionId",
3455
- "status",
3456
- "updatedAt",
3457
- "version"
3458
- ]);
3459
- return {
3460
- ...common,
3461
- status
3462
- };
3463
- case "succeeded":
3464
- exact(source, [
3465
- "createdAt",
3466
- "flowId",
3467
- "operationId",
3468
- "publicationId",
3469
- "revisionId",
3470
- "status",
3471
- "updatedAt",
3472
- "version"
3473
- ]);
3474
- return {
3475
- ...common,
3476
- publicationId: string(source.publicationId),
3477
- status
3478
- };
3479
- case "failed": {
3480
- exact(source, [
3481
- "createdAt",
3482
- "flowId",
3483
- "issue",
3484
- "operationId",
3485
- "revisionId",
3486
- "status",
3487
- "updatedAt",
3488
- "version"
3489
- ]);
3490
- const issue = record$1(source.issue);
3491
- const nodeId = issue.nodeId;
3492
- exact(issue, [
3493
- "code",
3494
- "message",
3495
- ...nodeId == null ? [] : ["nodeId"]
3496
- ]);
3497
- return {
3498
- ...common,
3499
- issue: {
3500
- code: string(issue.code),
3501
- message: string(issue.message),
3502
- ...nodeId == null ? {} : { nodeId: string(nodeId) }
3503
- },
3504
- status
3505
- };
3506
- }
3507
- default: return invalidResponse();
3508
- }
3509
- }
3510
- function live(value) {
3511
- const source = record$1(value);
3512
- const status = source.status;
3513
- const candidate = source.publication;
3514
- if (source.version != 1 || typeof source.hasUnpublishedChanges != "boolean") return invalidResponse();
3515
- if (status != "not-published" && status != "runnable" && status != "suspended") return invalidResponse();
3516
- if (status == "not-published" && candidate !== null) return invalidResponse();
3517
- if (status != "not-published" && candidate === null) return invalidResponse();
3518
- return {
3519
- flowId: string(source.flowId),
3520
- hasUnpublishedChanges: source.hasUnpublishedChanges,
3521
- publication: candidate === null ? null : publication$7(candidate),
3522
- revision: integer(source.revision),
3523
- status,
3524
- version: 1
3525
- };
3526
- }
3527
- function publicationPage(value) {
3528
- const source = record$1(value);
3529
- const nextCursor = source.nextCursor;
3530
- const total = source.total;
3531
- if (source.version != 1 || !Array.isArray(source.publications)) return invalidResponse();
3532
- if (nextCursor != null && typeof nextCursor != "string") return invalidResponse();
3533
- if (total != null && !Number.isSafeInteger(total)) return invalidResponse();
3534
- return {
3535
- ...nextCursor == null ? {} : { nextCursor },
3536
- publications: source.publications.map(publication$7),
3537
- ...total == null ? {} : { total },
3538
- version: 1
3539
- };
3540
- }
3541
- //#endregion
3542
3059
  //#region src/control/common/revisionDecoders.ts
3543
3060
  function revisionMetadata(value) {
3544
3061
  const source = record$1(value);
@@ -4484,21 +4001,14 @@ var ControlClient = class {
4484
4001
  method: "POST"
4485
4002
  }));
4486
4003
  }
4004
+ async getLiveDetails(flowId, signal) {
4005
+ const details = decodeLiveDetails(await this.request(`/v1/flows/${segment$1(flowId)}/live/details`, { signal }));
4006
+ if (details.flowId != flowId) return invalidResponse();
4007
+ return details;
4008
+ }
4487
4009
  async getLive(flowId, signal) {
4488
4010
  return live(await this.request(`/v1/flows/${segment$1(flowId)}/live`, { signal }));
4489
4011
  }
4490
- async listPublicationResources(flowId, publicationId) {
4491
- const query = publicationId == null ? "" : `?publicationId=${encodeURIComponent(publicationId)}`;
4492
- const result = decodePublicationResources(await this.request(`/v1/flows/${segment$1(flowId)}/resources${query}`));
4493
- if (result.flowId != flowId || publicationId != null && result.publicationId != publicationId) return invalidResponse();
4494
- return result;
4495
- }
4496
- async getPublicationResource(flowId, resourceId, publicationId) {
4497
- const query = publicationId == null ? "" : `?publicationId=${encodeURIComponent(publicationId)}`;
4498
- const result = decodePublicationResource(await this.request(`/v1/flows/${segment$1(flowId)}/resources/${segment$1(resourceId)}${query}`));
4499
- if (result.flowId != flowId || result.resource.resourceId != resourceId || publicationId != null && result.publicationId != publicationId) return invalidResponse();
4500
- return result;
4501
- }
4502
4012
  async listPublications(flowId, options = {}, signal) {
4503
4013
  const parameters = new URLSearchParams();
4504
4014
  if (options.cursor != null) parameters.set("cursor", options.cursor);
@@ -4759,7 +4269,6 @@ var errorKeys = {
4759
4269
  [controlErrorCode.pageInvalidCursor]: "notice.error.pageInvalidCursor",
4760
4270
  [controlErrorCode.publicationConflict]: "notice.error.publicationConflict",
4761
4271
  [controlErrorCode.publicationNotFound]: "notice.error.publicationNotFound",
4762
- [controlErrorCode.resourceNotFound]: "notice.error.resourceNotFound",
4763
4272
  [controlErrorCode.publicationUnsupported]: "notice.error.publicationUnsupported",
4764
4273
  [controlErrorCode.publishOperationNotFound]: "notice.error.publishOperationNotFound",
4765
4274
  [controlErrorCode.routeNotFound]: "notice.error.routeNotFound",
@@ -11347,7 +10856,6 @@ var resources$1 = {
11347
10856
  "pageInvalidCursor": "This list changed while it was loading. Reload the list.",
11348
10857
  "publicationConflict": "The publication state changed since it was loaded. Refresh and try again.",
11349
10858
  "publicationNotFound": "This Publication does not exist or was deleted. Refresh the Publication list.",
11350
- "resourceNotFound": "The resource was not found in this publication.",
11351
10859
  "publicationUnsupported": "This Flow cannot be published because an existing Trigger subscription cannot be changed safely.",
11352
10860
  "publishOperationNotFound": "The publishing status is no longer available. Start publishing again.",
11353
10861
  "responseInvalid": "The service returned data that Open Flow could not read. Try again later.",
@@ -11903,6 +11411,14 @@ var resources$1 = {
11903
11411
  "description": "Description",
11904
11412
  "required": "Input required"
11905
11413
  },
11414
+ webhookDeployment: {
11415
+ "title": "Live Webhook",
11416
+ "unpublished": "Publish this flow to generate a Webhook URL.",
11417
+ "unpublishedChanges": "Live uses the published version. Draft changes are not live yet.",
11418
+ "loadFailed": "Could not load the Webhook deployment.",
11419
+ "pending": "The Webhook URL is not available yet.",
11420
+ "copyFailed": "Could not copy. Select the URL and copy it manually."
11421
+ },
11906
11422
  webhookEditor: {
11907
11423
  "webhookAddHeader": "Add header",
11908
11424
  "webhookDeleteHeader": "Delete response header",
@@ -12780,7 +12296,6 @@ var resources$1 = {
12780
12296
  "pageInvalidCursor": "列表加载期间内容已发生变化,请重新加载列表。",
12781
12297
  "publicationConflict": "发布状态已发生变化,请刷新后重试。",
12782
12298
  "publicationNotFound": "找不到这条发布记录,请刷新发布列表。",
12783
- "resourceNotFound": "此发布版本中找不到该资源。",
12784
12299
  "publicationUnsupported": "现有 Trigger 订阅无法安全变更,因此无法发布此工作流。",
12785
12300
  "publishOperationNotFound": "本次发布状态已不可用,请重新发起发布。",
12786
12301
  "responseInvalid": "服务返回了无法识别的数据,请稍后重试。",
@@ -13336,6 +12851,14 @@ var resources$1 = {
13336
12851
  "description": "说明",
13337
12852
  "required": "需要输入"
13338
12853
  },
12854
+ webhookDeployment: {
12855
+ "title": "线上 Webhook",
12856
+ "unpublished": "发布后生成 Webhook 地址。",
12857
+ "unpublishedChanges": "线上使用已发布版本,草稿修改尚未生效。",
12858
+ "loadFailed": "无法加载 Webhook 部署信息。",
12859
+ "pending": "Webhook 地址暂未就绪。",
12860
+ "copyFailed": "复制失败,请选中地址手动复制。"
12861
+ },
13339
12862
  webhookEditor: {
13340
12863
  "webhookAddHeader": "添加响应头",
13341
12864
  "webhookDeleteHeader": "删除响应头",
@@ -14213,7 +13736,6 @@ var resources$1 = {
14213
13736
  "pageInvalidCursor": "列表載入期間內容已變更,請重新載入列表。",
14214
13737
  "publicationConflict": "發布狀態已變更,請重新整理後再試一次。",
14215
13738
  "publicationNotFound": "找不到這筆發布記錄,請重新整理發布列表。",
14216
- "resourceNotFound": "此發布版本中找不到該資源。",
14217
13739
  "publicationUnsupported": "現有的 Trigger 訂閱無法安全變更,因此無法發布此 Flow。",
14218
13740
  "publishOperationNotFound": "本次發布狀態已無法使用,請重新發起發布。",
14219
13741
  "responseInvalid": "服務傳回了無法識別的資料,請稍後再試一次。",
@@ -14769,6 +14291,14 @@ var resources$1 = {
14769
14291
  "description": "說明",
14770
14292
  "required": "需要輸入"
14771
14293
  },
14294
+ webhookDeployment: {
14295
+ "title": "線上 Webhook",
14296
+ "unpublished": "發佈後產生 Webhook 位址。",
14297
+ "unpublishedChanges": "線上使用已發佈版本,草稿修改尚未生效。",
14298
+ "loadFailed": "無法載入 Webhook 部署資訊。",
14299
+ "pending": "Webhook 位址尚未就緒。",
14300
+ "copyFailed": "複製失敗,請選取位址手動複製。"
14301
+ },
14772
14302
  webhookEditor: {
14773
14303
  "webhookAddHeader": "新增標頭",
14774
14304
  "webhookDeleteHeader": "刪除回應標頭",
@@ -15442,7 +14972,6 @@ var resources$1 = {
15442
14972
  "pageInvalidCursor": "読み込み中に一覧が変更されました。一覧を再読み込みしてください。",
15443
14973
  "publicationConflict": "公開状態は読み込み後に変更されました。更新してから再試行してください。",
15444
14974
  "publicationNotFound": "この Publication は存在しないか、削除されています。Publication 一覧を更新してください。",
15445
- "resourceNotFound": "この公開バージョンにリソースが見つかりません。",
15446
14975
  "publicationUnsupported": "既存の Trigger サブスクリプションを安全に変更できないため、この Flow は公開できません。",
15447
14976
  "publishOperationNotFound": "公開状況を確認できなくなりました。もう一度公開を開始してください。",
15448
14977
  "responseInvalid": "サービスから読み取れないデータが返されました。しばらくしてから再試行してください。",
@@ -15998,6 +15527,14 @@ var resources$1 = {
15998
15527
  "description": "説明",
15999
15528
  "required": "入力が必要"
16000
15529
  },
15530
+ webhookDeployment: {
15531
+ "title": "公開中の Webhook",
15532
+ "unpublished": "公開すると Webhook URL が生成されます。",
15533
+ "unpublishedChanges": "公開済みのバージョンが使用されています。下書きの変更はまだ反映されていません。",
15534
+ "loadFailed": "Webhook のデプロイ情報を読み込めませんでした。",
15535
+ "pending": "Webhook URL はまだ利用できません。",
15536
+ "copyFailed": "コピーできませんでした。URL を選択して手動でコピーしてください。"
15537
+ },
16001
15538
  webhookEditor: {
16002
15539
  "webhookAddHeader": "レスポンスヘッダーを追加",
16003
15540
  "webhookDeleteHeader": "レスポンスヘッダーを削除",
@@ -16875,7 +16412,6 @@ var resources$1 = {
16875
16412
  "pageInvalidCursor": "목록을 불러오는 중에 내용이 변경되었습니다. 목록을 다시 불러오세요.",
16876
16413
  "publicationConflict": "불러온 뒤 게시 상태가 변경되었습니다. 새로 고친 뒤 다시 시도하세요.",
16877
16414
  "publicationNotFound": "이 Publication이 없거나 삭제되었습니다. Publication 목록을 새로 고치세요.",
16878
- "resourceNotFound": "이 게시 버전에서 리소스를 찾을 수 없습니다.",
16879
16415
  "publicationUnsupported": "기존 Trigger 구독을 안전하게 변경할 수 없어 이 Flow를 게시할 수 없습니다.",
16880
16416
  "publishOperationNotFound": "게시 상태를 더 이상 확인할 수 없습니다. 게시를 다시 시작하세요.",
16881
16417
  "responseInvalid": "서비스에서 Open Flow가 읽을 수 없는 데이터를 반환했습니다. 나중에 다시 시도하세요.",
@@ -17431,6 +16967,14 @@ var resources$1 = {
17431
16967
  "description": "설명",
17432
16968
  "required": "입력 필요"
17433
16969
  },
16970
+ webhookDeployment: {
16971
+ "title": "배포된 Webhook",
16972
+ "unpublished": "게시하면 Webhook URL이 생성됩니다.",
16973
+ "unpublishedChanges": "게시된 버전을 사용 중입니다. 초안 변경 사항은 아직 반영되지 않았습니다.",
16974
+ "loadFailed": "Webhook 배포 정보를 불러올 수 없습니다.",
16975
+ "pending": "Webhook URL이 아직 준비되지 않았습니다.",
16976
+ "copyFailed": "복사하지 못했습니다. URL을 선택하여 직접 복사하세요."
16977
+ },
17434
16978
  webhookEditor: {
17435
16979
  "webhookAddHeader": "헤더 추가",
17436
16980
  "webhookDeleteHeader": "응답 헤더 삭제",
@@ -18104,7 +17648,6 @@ var resources$1 = {
18104
17648
  "pageInvalidCursor": "Список изменился во время загрузки. Загрузите список заново.",
18105
17649
  "publicationConflict": "Состояние публикации изменилось после загрузки. Обновите данные и повторите попытку.",
18106
17650
  "publicationNotFound": "Эта публикация не существует или была удалена. Обновите список публикаций.",
18107
- "resourceNotFound": "Ресурс не найден в этой публикации.",
18108
17651
  "publicationUnsupported": "Этот Flow нельзя опубликовать, так как существующую подписку Trigger невозможно безопасно изменить.",
18109
17652
  "publishOperationNotFound": "Состояние публикации больше недоступно. Запустите публикацию снова.",
18110
17653
  "responseInvalid": "Сервис вернул данные, которые Open Flow не может прочитать. Повторите попытку позже.",
@@ -18660,6 +18203,14 @@ var resources$1 = {
18660
18203
  "description": "Описание",
18661
18204
  "required": "Требуется вход"
18662
18205
  },
18206
+ webhookDeployment: {
18207
+ "title": "Опубликованный Webhook",
18208
+ "unpublished": "Опубликуйте процесс, чтобы создать URL Webhook.",
18209
+ "unpublishedChanges": "Используется опубликованная версия. Изменения черновика ещё не применены.",
18210
+ "loadFailed": "Не удалось загрузить данные развёртывания Webhook.",
18211
+ "pending": "URL Webhook пока недоступен.",
18212
+ "copyFailed": "Не удалось скопировать. Выделите URL и скопируйте его вручную."
18213
+ },
18663
18214
  webhookEditor: {
18664
18215
  "webhookAddHeader": "Добавить заголовок",
18665
18216
  "webhookDeleteHeader": "Удалить заголовок ответа",
@@ -19396,7 +18947,6 @@ var resources$1 = {
19396
18947
  "pageInvalidCursor": "La liste a changé pendant son chargement. Rechargez-la.",
19397
18948
  "publicationConflict": "L’état de la Publication a changé depuis son chargement. Actualisez, puis réessayez.",
19398
18949
  "publicationNotFound": "Cette Publication n’existe pas ou a été supprimée. Actualisez la liste des Publications.",
19399
- "resourceNotFound": "La ressource est introuvable dans cette publication.",
19400
18950
  "publicationUnsupported": "Ce Flow ne peut pas être publié, car un abonnement Trigger existant ne peut pas être modifié en toute sécurité.",
19401
18951
  "publishOperationNotFound": "L’état de la publication n’est plus disponible. Relancez la publication.",
19402
18952
  "responseInvalid": "Le service a renvoyé des données illisibles par Open Flow. Réessayez plus tard.",
@@ -19952,6 +19502,14 @@ var resources$1 = {
19952
19502
  "description": "Description",
19953
19503
  "required": "Entrée requise"
19954
19504
  },
19505
+ webhookDeployment: {
19506
+ "title": "Webhook en ligne",
19507
+ "unpublished": "Publiez ce flux pour générer une URL Webhook.",
19508
+ "unpublishedChanges": "La version publiée est utilisée. Les modifications du brouillon ne sont pas encore en ligne.",
19509
+ "loadFailed": "Impossible de charger le déploiement du Webhook.",
19510
+ "pending": "L’URL Webhook n’est pas encore disponible.",
19511
+ "copyFailed": "Échec de la copie. Sélectionnez l’URL et copiez-la manuellement."
19512
+ },
19955
19513
  webhookEditor: {
19956
19514
  "webhookAddHeader": "Ajouter un en-tête",
19957
19515
  "webhookDeleteHeader": "Supprimer l'en-tête de réponse",
@@ -26820,194 +26378,708 @@ function VirtualScrollArea({ listRef, className, onScrollIntent, onWheel, onKeyD
26820
26378
  ].includes(event.key)) onScrollIntent?.();
26821
26379
  onKeyDown?.(event);
26822
26380
  }
26823
- })
26381
+ })
26382
+ });
26383
+ }
26384
+ //#endregion
26385
+ //#region src/ui/browser/popover.tsx
26386
+ function Popover({ ...props }) {
26387
+ return /* @__PURE__ */ jsx(PopoverRoot, {
26388
+ "data-slot": "popover",
26389
+ ...props
26390
+ });
26391
+ }
26392
+ var PopoverTrigger = React.forwardRef(function PopoverTrigger(props, ref) {
26393
+ return /* @__PURE__ */ jsx(PopoverTrigger$1, {
26394
+ "data-slot": "popover-trigger",
26395
+ ...props,
26396
+ ref
26397
+ });
26398
+ });
26399
+ function PopoverContent({ className, positionerClassName, positionerStyle, align = "center", alignOffset = 0, anchor, collisionBoundary, collisionAvoidance, positionMethod, container, keepMounted, side = "bottom", sideOffset = 4, ...props }) {
26400
+ return /* @__PURE__ */ jsx(PopoverPortal, {
26401
+ container,
26402
+ keepMounted,
26403
+ className: "contents",
26404
+ children: /* @__PURE__ */ jsx(PopoverPositioner, {
26405
+ collisionBoundary,
26406
+ collisionAvoidance,
26407
+ positionMethod,
26408
+ anchor,
26409
+ align,
26410
+ alignOffset,
26411
+ side,
26412
+ sideOffset,
26413
+ className: cn("isolate z-50", positionerClassName),
26414
+ style: positionerStyle,
26415
+ children: /* @__PURE__ */ jsx(PopoverPopup, {
26416
+ "data-slot": "popover-content",
26417
+ className: cn("z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 motion-reduce:animate-none motion-reduce:transition-none", className),
26418
+ ...props
26419
+ })
26420
+ })
26421
+ });
26422
+ }
26423
+ function PopoverHeader({ className, ...props }) {
26424
+ return /* @__PURE__ */ jsx("div", {
26425
+ "data-slot": "popover-header",
26426
+ className: cn("flex flex-col gap-0.5 text-sm", className),
26427
+ ...props
26428
+ });
26429
+ }
26430
+ function PopoverTitle({ className, ...props }) {
26431
+ return /* @__PURE__ */ jsx(PopoverTitle$1, {
26432
+ "data-slot": "popover-title",
26433
+ className: cn("m-0 text-sm font-medium", className),
26434
+ ...props
26435
+ });
26436
+ }
26437
+ function PopoverDescription({ className, ...props }) {
26438
+ return /* @__PURE__ */ jsx(PopoverDescription$1, {
26439
+ "data-slot": "popover-description",
26440
+ className: cn("text-muted-foreground", className),
26441
+ ...props
26442
+ });
26443
+ }
26444
+ /** Additional property controls, anchored beside their owning field. */
26445
+ function PopoverPanelContent({ title, sectionTitle, closeLabel, footer, children, ...props }) {
26446
+ return /* @__PURE__ */ jsxs(PopoverContent, {
26447
+ collisionBoundary: [],
26448
+ collisionAvoidance: {
26449
+ side: "flip",
26450
+ align: "shift",
26451
+ fallbackAxisSide: "none"
26452
+ },
26453
+ positionMethod: "fixed",
26454
+ side: "left",
26455
+ align: "start",
26456
+ sideOffset: 2,
26457
+ ...props,
26458
+ className: cn("w-80 max-w-[calc(100vw-24px)] max-h-[min(80vh,680px,var(--available-height))] gap-0 overflow-hidden bg-popover p-0 text-xs [--ui-control-radius:6px]", props.className),
26459
+ children: [
26460
+ /* @__PURE__ */ jsxs("div", {
26461
+ className: "flex h-10 shrink-0 items-center gap-2 px-3",
26462
+ children: [/* @__PURE__ */ jsxs(PopoverTitle, {
26463
+ className: "flex min-w-0 flex-1 items-center text-sm",
26464
+ children: [/* @__PURE__ */ jsx("span", {
26465
+ className: "shrink-0",
26466
+ children: title
26467
+ }), sectionTitle != null && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
26468
+ className: "shrink-0 px-1 text-muted-foreground",
26469
+ children: "·"
26470
+ }), /* @__PURE__ */ jsx("span", {
26471
+ className: "flex min-w-0 items-center gap-1 overflow-hidden whitespace-nowrap text-muted-foreground [&>i]:shrink-0",
26472
+ children: sectionTitle
26473
+ })] })]
26474
+ }), /* @__PURE__ */ jsx(PopoverClose, {
26475
+ render: /* @__PURE__ */ jsx(Button, {
26476
+ type: "button",
26477
+ variant: "ghost",
26478
+ size: "icon-sm",
26479
+ "aria-label": closeLabel
26480
+ }),
26481
+ children: /* @__PURE__ */ jsx("i", {
26482
+ "aria-hidden": "true",
26483
+ className: "i-lucide-light:x text-base"
26484
+ })
26485
+ })]
26486
+ }),
26487
+ /* @__PURE__ */ jsx("div", { className: "mx-2 h-px shrink-0 bg-border/50" }),
26488
+ /* @__PURE__ */ jsx(ScrollArea, {
26489
+ className: "min-h-0 h-auto",
26490
+ defer: false,
26491
+ children: /* @__PURE__ */ jsx("div", {
26492
+ className: "flex flex-col gap-3 p-3",
26493
+ children
26494
+ })
26495
+ }),
26496
+ footer && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", { className: "mx-2 h-px shrink-0 bg-border/50" }), /* @__PURE__ */ jsx("div", {
26497
+ className: "flex shrink-0 items-center gap-2 px-3 py-3",
26498
+ children: footer
26499
+ })] })
26500
+ ]
26501
+ });
26502
+ }
26503
+ //#endregion
26504
+ //#region src/workbench/browser/runtime/navigationLink.ts
26505
+ function followWorkbenchLink(event, navigate) {
26506
+ if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
26507
+ event.preventDefault();
26508
+ navigate();
26509
+ }
26510
+ //#endregion
26511
+ //#region src/ui/browser/idTooltip.tsx
26512
+ function IdTooltip$1({ copyLabel, copiedLabel, value, label, trigger, container, alignOffset = 0, children }) {
26513
+ const [open, setOpen] = useState(false);
26514
+ const [copied, setCopied] = useState(false);
26515
+ return /* @__PURE__ */ jsxs(Tooltip, {
26516
+ open,
26517
+ onOpenChange: (nextOpen) => {
26518
+ setOpen(nextOpen);
26519
+ setCopied(false);
26520
+ },
26521
+ children: [/* @__PURE__ */ jsx(TooltipTrigger, {
26522
+ className: "cursor-help",
26523
+ closeOnClick: false,
26524
+ onClick: () => setOpen(true),
26525
+ render: trigger,
26526
+ children: label
26527
+ }), /* @__PURE__ */ jsxs(TooltipContent, {
26528
+ align: "start",
26529
+ alignOffset,
26530
+ className: "max-w-[min(440px,calc(100vw-32px))] flex-col items-stretch gap-2 p-1 pr-2",
26531
+ collisionBoundary: [],
26532
+ container,
26533
+ positionMethod: "fixed",
26534
+ side: "top",
26535
+ sideOffset: 6,
26536
+ children: [/* @__PURE__ */ jsxs("div", {
26537
+ className: "flex min-w-0 items-center gap-1",
26538
+ children: [/* @__PURE__ */ jsx(Button, {
26539
+ "aria-label": copied ? copiedLabel : copyLabel,
26540
+ className: "text-inherit hover:text-inherit hover:bg-[color-mix(in_srgb,currentColor_14%,transparent)]",
26541
+ onClick: () => {
26542
+ navigator.clipboard.writeText(value).then(() => setCopied(true));
26543
+ },
26544
+ size: "icon-xs",
26545
+ type: "button",
26546
+ variant: "ghost",
26547
+ children: /* @__PURE__ */ jsx("i", {
26548
+ "aria-hidden": "true",
26549
+ className: "i-lucide-light:copy"
26550
+ })
26551
+ }), /* @__PURE__ */ jsx("code", {
26552
+ className: "min-w-0 select-text break-all pl-0.5 text-inherit",
26553
+ translate: "no",
26554
+ children: value
26555
+ })]
26556
+ }), children]
26557
+ })]
26558
+ });
26559
+ }
26560
+ //#endregion
26561
+ //#region src/workbench/browser/runtime/shell/idTooltip.tsx
26562
+ function IdTooltip(props) {
26563
+ const t = useTranslate();
26564
+ return /* @__PURE__ */ jsx(IdTooltip$1, {
26565
+ ...props,
26566
+ copyLabel: t("resource.copyFlowId"),
26567
+ copiedLabel: t("resource.flowIdCopied")
26568
+ });
26569
+ }
26570
+ //#endregion
26571
+ //#region src/flow/common/nodeChanges.ts
26572
+ var codeTaskTemplate = `export default async function (inputs, context) {
26573
+ return { result: inputs.value }
26574
+ }
26575
+ `;
26576
+ var defaultCodeTaskPorts = {
26577
+ inputs: [{
26578
+ handle: "value",
26579
+ jsonSchema: { type: "string" },
26580
+ nullable: true,
26581
+ value: "foo"
26582
+ }],
26583
+ outputs: [{
26584
+ handle: "result",
26585
+ jsonSchema: {},
26586
+ nullable: true
26587
+ }]
26588
+ };
26589
+ function defaultNodeName(_content, node) {
26590
+ switch (node.kind) {
26591
+ case "condition": return "Condition";
26592
+ case "value": return "Fixed Values";
26593
+ case "approval": return "Approval";
26594
+ case "wait": return "Wait";
26595
+ case "task": return normalizeNodeName(node.task.name) || "Task";
26596
+ case "error": return "Flow Error";
26597
+ case "manual": return "Manual Trigger";
26598
+ case "webhook": return "Webhook";
26599
+ case "cron": return "Scheduled Trigger";
26600
+ case "integration":
26601
+ case "poll": return normalizeNodeName(node.definition.displayName) || "Trigger";
26602
+ }
26603
+ }
26604
+ function graphNameRepairs(content, targetGraph) {
26605
+ const names = /* @__PURE__ */ new Set();
26606
+ const changed = [];
26607
+ for (const [nodeId, node] of Object.entries(targetGraph.nodes)) {
26608
+ const requested = normalizeNodeName(node.name ?? "") || defaultNodeName(content, node);
26609
+ const name = nextNodeName(requested, names);
26610
+ names.add(name);
26611
+ if (node.name != name) changed.push({
26612
+ name,
26613
+ node,
26614
+ nodeId
26615
+ });
26616
+ }
26617
+ return changed.toReversed().map(({ name, node, nodeId }) => ({
26618
+ before: node.name,
26619
+ field: "name",
26620
+ kind: "graph.node.field.set",
26621
+ nodeId,
26622
+ value: name
26623
+ }));
26624
+ }
26625
+ function repairNodeNames(content) {
26626
+ return graphNameRepairs(content, content.document.graph);
26627
+ }
26628
+ function createCodeTask(identity, name, module = void 0, ports = defaultCodeTaskPorts) {
26629
+ return [{
26630
+ kind: "module.create",
26631
+ module: {
26632
+ ...module ?? {
26633
+ imports: [],
26634
+ source: codeTaskTemplate
26635
+ },
26636
+ name
26637
+ },
26638
+ moduleId: identity.moduleId
26639
+ }, {
26640
+ kind: "graph.node.create",
26641
+ node: {
26642
+ inputs: defaultInputs(ports.inputs),
26643
+ kind: "task",
26644
+ name,
26645
+ task: {
26646
+ capabilities: ports.capabilities ?? [{
26647
+ kind: "connector",
26648
+ mode: "independent",
26649
+ actions: []
26650
+ }],
26651
+ inputs: ports.inputs,
26652
+ moduleId: identity.moduleId,
26653
+ name,
26654
+ outputs: ports.outputs
26655
+ }
26656
+ },
26657
+ nodeId: identity.nodeId
26658
+ }];
26659
+ }
26660
+ function createManagedTask(identity, task) {
26661
+ return [{
26662
+ kind: "graph.node.create",
26663
+ node: {
26664
+ inputs: defaultInputs(task.inputs),
26665
+ kind: "task",
26666
+ name: task.name,
26667
+ task
26668
+ },
26669
+ nodeId: identity.nodeId
26670
+ }];
26671
+ }
26672
+ function createAgentTask(identity, name, defaults = {}) {
26673
+ return createManagedTask(identity, {
26674
+ name,
26675
+ inputs: defaults.inputs ?? [{
26676
+ handle: "input",
26677
+ jsonSchema: { type: "string" },
26678
+ nullable: false,
26679
+ value: ""
26680
+ }],
26681
+ outputs: [{
26682
+ handle: "output",
26683
+ jsonSchema: { type: "string" },
26684
+ nullable: false,
26685
+ description: defaults.outputDescription ?? "The final result produced by the Agent."
26686
+ }],
26687
+ executor: {
26688
+ kind: "agent",
26689
+ model: "deepseek-v4-flash",
26690
+ prompt: defaults.prompt ?? "Summarize the following content, highlighting key points and next steps.\n\n{{input}}",
26691
+ maxRounds: 10,
26692
+ tools: []
26693
+ }
26694
+ });
26695
+ }
26696
+ function createLlmTask(identity, name, mode, outputDescription, options = {}) {
26697
+ const values = options.inputs ?? {};
26698
+ return createManagedTask(identity, {
26699
+ executor: {
26700
+ kind: "llm",
26701
+ mode
26702
+ },
26703
+ inputs: [
26704
+ {
26705
+ handle: "messages",
26706
+ jsonSchema: {
26707
+ items: { type: "object" },
26708
+ type: "array"
26709
+ },
26710
+ nullable: true,
26711
+ value: llmInputValue(values, "messages", null)
26712
+ },
26713
+ {
26714
+ handle: "input",
26715
+ jsonSchema: { type: "string" },
26716
+ nullable: false,
26717
+ value: llmInputValue(values, "input", "Alex")
26718
+ },
26719
+ {
26720
+ handle: "template",
26721
+ jsonSchema: {
26722
+ items: { type: "object" },
26723
+ minItems: 1,
26724
+ type: "array"
26725
+ },
26726
+ nullable: false,
26727
+ value: llmInputValue(values, "template", [{
26728
+ content: "Hello, I'm {{input}}",
26729
+ role: "user"
26730
+ }])
26731
+ },
26732
+ {
26733
+ handle: "model",
26734
+ jsonSchema: { type: "object" },
26735
+ nullable: false,
26736
+ value: llmInputValue(values, "model", { model: "deepseek-v4-flash" })
26737
+ }
26738
+ ],
26739
+ name,
26740
+ outputs: [{
26741
+ ...options.output,
26742
+ description: options.output?.description ?? outputDescription,
26743
+ handle: "output",
26744
+ jsonSchema: options.output?.jsonSchema ?? (mode == "chat" ? { type: "string" } : {}),
26745
+ nullable: options.output?.nullable ?? false
26746
+ }]
26824
26747
  });
26825
26748
  }
26826
- //#endregion
26827
- //#region src/ui/browser/popover.tsx
26828
- function Popover({ ...props }) {
26829
- return /* @__PURE__ */ jsx(PopoverRoot, {
26830
- "data-slot": "popover",
26831
- ...props
26832
- });
26749
+ function createCondition(nodeId, name) {
26750
+ return [{
26751
+ kind: "graph.node.create",
26752
+ node: {
26753
+ cases: [{
26754
+ groups: [{ expressions: [{
26755
+ left: { kind: "value" },
26756
+ operator: "==",
26757
+ right: { kind: "value" }
26758
+ }] }],
26759
+ output: "case"
26760
+ }],
26761
+ matchMode: "first",
26762
+ inputs: {},
26763
+ kind: "condition",
26764
+ name
26765
+ },
26766
+ nodeId
26767
+ }];
26833
26768
  }
26834
- var PopoverTrigger = React.forwardRef(function PopoverTrigger(props, ref) {
26835
- return /* @__PURE__ */ jsx(PopoverTrigger$1, {
26836
- "data-slot": "popover-trigger",
26837
- ...props,
26838
- ref
26839
- });
26840
- });
26841
- function PopoverContent({ className, positionerClassName, positionerStyle, align = "center", alignOffset = 0, anchor, collisionBoundary, collisionAvoidance, positionMethod, container, keepMounted, side = "bottom", sideOffset = 4, ...props }) {
26842
- return /* @__PURE__ */ jsx(PopoverPortal, {
26843
- container,
26844
- keepMounted,
26845
- className: "contents",
26846
- children: /* @__PURE__ */ jsx(PopoverPositioner, {
26847
- collisionBoundary,
26848
- collisionAvoidance,
26849
- positionMethod,
26850
- anchor,
26851
- align,
26852
- alignOffset,
26853
- side,
26854
- sideOffset,
26855
- className: cn("isolate z-50", positionerClassName),
26856
- style: positionerStyle,
26857
- children: /* @__PURE__ */ jsx(PopoverPopup, {
26858
- "data-slot": "popover-content",
26859
- className: cn("z-50 flex w-72 origin-(--transform-origin) flex-col gap-2.5 rounded-lg bg-popover p-2.5 text-sm text-popover-foreground shadow-md ring-1 ring-foreground/10 outline-hidden duration-100 data-[side=bottom]:slide-in-from-top-2 data-[side=inline-end]:slide-in-from-left-2 data-[side=inline-start]:slide-in-from-right-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95 motion-reduce:animate-none motion-reduce:transition-none", className),
26860
- ...props
26861
- })
26862
- })
26863
- });
26769
+ function createValue(nodeId, name, values = [{
26770
+ handle: "value",
26771
+ jsonSchema: {},
26772
+ nullable: true,
26773
+ value: null
26774
+ }]) {
26775
+ return [{
26776
+ kind: "graph.node.create",
26777
+ node: {
26778
+ inputs: {},
26779
+ kind: "value",
26780
+ name,
26781
+ values
26782
+ },
26783
+ nodeId
26784
+ }];
26864
26785
  }
26865
- function PopoverHeader({ className, ...props }) {
26866
- return /* @__PURE__ */ jsx("div", {
26867
- "data-slot": "popover-header",
26868
- className: cn("flex flex-col gap-0.5 text-sm", className),
26869
- ...props
26870
- });
26786
+ function createWait(nodeId, name) {
26787
+ return [{
26788
+ kind: "graph.node.create",
26789
+ node: {
26790
+ inputDefinitions: [],
26791
+ inputs: {},
26792
+ kind: "wait",
26793
+ name,
26794
+ prompt: name
26795
+ },
26796
+ nodeId
26797
+ }];
26871
26798
  }
26872
- function PopoverTitle({ className, ...props }) {
26873
- return /* @__PURE__ */ jsx(PopoverTitle$1, {
26874
- "data-slot": "popover-title",
26875
- className: cn("m-0 text-sm font-medium", className),
26876
- ...props
26877
- });
26799
+ function createApproval(nodeId, name) {
26800
+ return [{
26801
+ kind: "graph.node.create",
26802
+ node: {
26803
+ inputDefinitions: [],
26804
+ inputs: {},
26805
+ kind: "approval",
26806
+ name,
26807
+ prompt: name
26808
+ },
26809
+ nodeId
26810
+ }];
26878
26811
  }
26879
- function PopoverDescription({ className, ...props }) {
26880
- return /* @__PURE__ */ jsx(PopoverDescription$1, {
26881
- "data-slot": "popover-description",
26882
- className: cn("text-muted-foreground", className),
26883
- ...props
26884
- });
26812
+ function createBuiltinTrigger(nodeId, node) {
26813
+ return [{
26814
+ kind: "graph.node.create",
26815
+ node,
26816
+ nodeId
26817
+ }];
26885
26818
  }
26886
- /** Additional property controls, anchored beside their owning field. */
26887
- function PopoverPanelContent({ title, sectionTitle, closeLabel, footer, children, ...props }) {
26888
- return /* @__PURE__ */ jsxs(PopoverContent, {
26889
- collisionBoundary: [],
26890
- collisionAvoidance: {
26891
- side: "flip",
26892
- align: "shift",
26893
- fallbackAxisSide: "none"
26819
+ function createProviderTrigger(nodeId, definition, options) {
26820
+ const name = options.name ?? definition.displayName;
26821
+ return [{
26822
+ kind: "graph.node.create",
26823
+ node: definition.type == "poll" ? {
26824
+ ...options.connectionId == null ? {} : { connectionId: options.connectionId },
26825
+ config: inputValues(options.config),
26826
+ definition,
26827
+ kind: "poll",
26828
+ name,
26829
+ pollTimes: options.schedule ?? [{
26830
+ type: "every",
26831
+ unit: "minute",
26832
+ value: 5
26833
+ }]
26834
+ } : {
26835
+ ...options.connectionId == null ? {} : { connectionId: options.connectionId },
26836
+ config: inputValues(options.config),
26837
+ definition,
26838
+ kind: "integration",
26839
+ name
26894
26840
  },
26895
- positionMethod: "fixed",
26896
- side: "left",
26897
- align: "start",
26898
- sideOffset: 2,
26899
- ...props,
26900
- className: cn("w-80 max-w-[calc(100vw-24px)] max-h-[min(80vh,680px,var(--available-height))] gap-0 overflow-hidden bg-popover p-0 text-xs [--ui-control-radius:6px]", props.className),
26901
- children: [
26902
- /* @__PURE__ */ jsxs("div", {
26903
- className: "flex h-10 shrink-0 items-center gap-2 px-3",
26904
- children: [/* @__PURE__ */ jsxs(PopoverTitle, {
26905
- className: "flex min-w-0 flex-1 items-center text-sm",
26906
- children: [/* @__PURE__ */ jsx("span", {
26907
- className: "shrink-0",
26908
- children: title
26909
- }), sectionTitle != null && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("span", {
26910
- className: "shrink-0 px-1 text-muted-foreground",
26911
- children: "·"
26912
- }), /* @__PURE__ */ jsx("span", {
26913
- className: "flex min-w-0 items-center gap-1 overflow-hidden whitespace-nowrap text-muted-foreground [&>i]:shrink-0",
26914
- children: sectionTitle
26915
- })] })]
26916
- }), /* @__PURE__ */ jsx(PopoverClose, {
26917
- render: /* @__PURE__ */ jsx(Button, {
26918
- type: "button",
26919
- variant: "ghost",
26920
- size: "icon-sm",
26921
- "aria-label": closeLabel
26922
- }),
26923
- children: /* @__PURE__ */ jsx("i", {
26924
- "aria-hidden": "true",
26925
- className: "i-lucide-light:x text-base"
26926
- })
26927
- })]
26928
- }),
26929
- /* @__PURE__ */ jsx("div", { className: "mx-2 h-px shrink-0 bg-border/50" }),
26930
- /* @__PURE__ */ jsx(ScrollArea, {
26931
- className: "min-h-0 h-auto",
26932
- defer: false,
26933
- children: /* @__PURE__ */ jsx("div", {
26934
- className: "flex flex-col gap-3 p-3",
26935
- children
26936
- })
26937
- }),
26938
- footer && /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", { className: "mx-2 h-px shrink-0 bg-border/50" }), /* @__PURE__ */ jsx("div", {
26939
- className: "flex shrink-0 items-center gap-2 px-3 py-3",
26940
- children: footer
26941
- })] })
26942
- ]
26841
+ nodeId
26842
+ }];
26843
+ }
26844
+ function deleteNodes(content, nodeIds) {
26845
+ const nodes = content.document.graph?.nodes;
26846
+ if (nodes == null) return [];
26847
+ return cleanVariableBindings(content, nodeIds.flatMap((nodeId) => {
26848
+ const node = nodes[nodeId];
26849
+ if (node == null) return [];
26850
+ return [{
26851
+ kind: "graph.node.delete",
26852
+ nodeId
26853
+ }, ...node.kind == "task" && "moduleId" in node.task ? [{
26854
+ kind: "module.delete",
26855
+ moduleId: node.task.moduleId
26856
+ }] : []];
26857
+ }));
26858
+ }
26859
+ function updateSettings(content, nodeId, settings) {
26860
+ const node = content.document.graph?.nodes[nodeId];
26861
+ if (node == null || !("inputs" in node)) return;
26862
+ const operations = [];
26863
+ if (node.name != settings.name) operations.push({
26864
+ before: node.name,
26865
+ field: "name",
26866
+ kind: "graph.node.field.set",
26867
+ nodeId,
26868
+ value: settings.name
26943
26869
  });
26870
+ if (node.maxExecutions != settings.maxExecutions) operations.push({
26871
+ before: node.maxExecutions,
26872
+ field: "maxExecutions",
26873
+ kind: "graph.node.field.set",
26874
+ nodeId,
26875
+ value: settings.maxExecutions
26876
+ });
26877
+ if (node.timeoutMs != settings.timeoutMs) operations.push({
26878
+ before: node.timeoutMs,
26879
+ field: "timeoutMs",
26880
+ kind: "graph.node.field.set",
26881
+ nodeId,
26882
+ value: settings.timeoutMs
26883
+ });
26884
+ return operations;
26944
26885
  }
26945
- //#endregion
26946
- //#region src/workbench/browser/runtime/navigationLink.ts
26947
- function followWorkbenchLink(event, navigate) {
26948
- if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;
26949
- event.preventDefault();
26950
- navigate();
26886
+ function setInputValue$1(content, nodeId, handle, value) {
26887
+ return setInputValues(content, nodeId, { [handle]: value });
26951
26888
  }
26952
- //#endregion
26953
- //#region src/ui/browser/idTooltip.tsx
26954
- function IdTooltip$1({ copyLabel, copiedLabel, value, label, trigger, container, alignOffset = 0, children }) {
26955
- const [open, setOpen] = useState(false);
26956
- const [copied, setCopied] = useState(false);
26957
- return /* @__PURE__ */ jsxs(Tooltip, {
26958
- open,
26959
- onOpenChange: (nextOpen) => {
26960
- setOpen(nextOpen);
26961
- setCopied(false);
26889
+ function setInputValues(content, nodeId, values) {
26890
+ const node = content.document.graph?.nodes[nodeId];
26891
+ if (node == null || !("inputs" in node)) return;
26892
+ const operations = [];
26893
+ for (const [handle, value] of Object.entries(values)) {
26894
+ const before = nodeInputMappings(node)[handle];
26895
+ const next = fixedInputValue(value);
26896
+ if (dequal(before, next)) continue;
26897
+ operations.push({
26898
+ before,
26899
+ handle,
26900
+ kind: "graph.node.input.set",
26901
+ nodeId,
26902
+ value: next
26903
+ });
26904
+ }
26905
+ return cleanVariableBindings(content, operations);
26906
+ }
26907
+ /** Restore inheritance for this form in one undoable change. */
26908
+ function resetInputValues(content, nodeId, handles) {
26909
+ const node = content.document.graph?.nodes[nodeId];
26910
+ if (node == null || !("inputs" in node)) return [];
26911
+ const mappings = nodeInputMappings(node);
26912
+ return cleanVariableBindings(content, [...new Set(handles)].flatMap((handle) => mappings[handle] == null ? [] : [{
26913
+ kind: "graph.node.input.set",
26914
+ nodeId,
26915
+ handle,
26916
+ before: mappings[handle],
26917
+ value: void 0
26918
+ }]));
26919
+ }
26920
+ function setInputSources(content, nodeId, handle, sources) {
26921
+ const node = content.document.graph?.nodes[nodeId];
26922
+ if (node == null || !("inputs" in node)) return [];
26923
+ return cleanVariableBindings(content, [{
26924
+ kind: "graph.node.input.set",
26925
+ nodeId,
26926
+ handle,
26927
+ before: nodeInputMappings(node)[handle],
26928
+ value: {
26929
+ kind: "sources",
26930
+ sources
26931
+ }
26932
+ }]);
26933
+ }
26934
+ function setInputVariable$1(content, nodeId, handle, name, bindingId) {
26935
+ const node = content.document.graph?.nodes[nodeId];
26936
+ if (node == null || !("inputs" in node)) return;
26937
+ const mapping = nodeInputMappings(node)[handle];
26938
+ const currentId = mapping?.kind == "sources" && mapping.sources.length == 1 && mapping.sources[0]?.kind == "binding" ? mapping.sources[0].bindingId : void 0;
26939
+ const current = currentId == null ? void 0 : content.document.bindings[currentId];
26940
+ const references = bindingReferences(content.document);
26941
+ if (currentId != null && current?.kind == "variable" && (references.get(currentId) ?? 0) == 1) {
26942
+ if (current.target == name) return [];
26943
+ return [{
26944
+ before: current.target,
26945
+ bindingId: currentId,
26946
+ kind: "binding.target.set",
26947
+ value: name
26948
+ }];
26949
+ }
26950
+ return [{
26951
+ binding: {
26952
+ kind: "variable",
26953
+ target: name
26962
26954
  },
26963
- children: [/* @__PURE__ */ jsx(TooltipTrigger, {
26964
- className: "cursor-help",
26965
- closeOnClick: false,
26966
- onClick: () => setOpen(true),
26967
- render: trigger,
26968
- children: label
26969
- }), /* @__PURE__ */ jsxs(TooltipContent, {
26970
- align: "start",
26971
- alignOffset,
26972
- className: "max-w-[min(440px,calc(100vw-32px))] flex-col items-stretch gap-2 p-1 pr-2",
26973
- collisionBoundary: [],
26974
- container,
26975
- positionMethod: "fixed",
26976
- side: "top",
26977
- sideOffset: 6,
26978
- children: [/* @__PURE__ */ jsxs("div", {
26979
- className: "flex min-w-0 items-center gap-1",
26980
- children: [/* @__PURE__ */ jsx(Button, {
26981
- "aria-label": copied ? copiedLabel : copyLabel,
26982
- className: "text-inherit hover:text-inherit hover:bg-[color-mix(in_srgb,currentColor_14%,transparent)]",
26983
- onClick: () => {
26984
- navigator.clipboard.writeText(value).then(() => setCopied(true));
26985
- },
26986
- size: "icon-xs",
26987
- type: "button",
26988
- variant: "ghost",
26989
- children: /* @__PURE__ */ jsx("i", {
26990
- "aria-hidden": "true",
26991
- className: "i-lucide-light:copy"
26992
- })
26993
- }), /* @__PURE__ */ jsx("code", {
26994
- className: "min-w-0 select-text break-all pl-0.5 text-inherit",
26995
- translate: "no",
26996
- children: value
26997
- })]
26998
- }), children]
26999
- })]
27000
- });
26955
+ bindingId,
26956
+ kind: "binding.create"
26957
+ }, ...cleanVariableBindings(content, [{
26958
+ before: mapping,
26959
+ handle,
26960
+ kind: "graph.node.input.set",
26961
+ nodeId,
26962
+ value: {
26963
+ kind: "sources",
26964
+ sources: [{
26965
+ bindingId,
26966
+ kind: "binding"
26967
+ }]
26968
+ }
26969
+ }])];
27001
26970
  }
27002
- //#endregion
27003
- //#region src/workbench/browser/runtime/shell/idTooltip.tsx
27004
- function IdTooltip(props) {
27005
- const t = useTranslate();
27006
- return /* @__PURE__ */ jsx(IdTooltip$1, {
27007
- ...props,
27008
- copyLabel: t("resource.copyFlowId"),
27009
- copiedLabel: t("resource.flowIdCopied")
27010
- });
26971
+ function cleanVariableBindings(content, operations) {
26972
+ const before = bindingReferences(content.document);
26973
+ const changed = applyFlowChanges$1(content, operations);
26974
+ const after = bindingReferences(changed.document);
26975
+ return [...operations, ...[...before.keys()].flatMap((bindingId) => after.has(bindingId) || changed.document.bindings[bindingId]?.kind != "variable" ? [] : [{
26976
+ bindingId,
26977
+ kind: "binding.delete"
26978
+ }])];
26979
+ }
26980
+ function bindingReferences(document) {
26981
+ const references = /* @__PURE__ */ new Map();
26982
+ const add = (bindingId) => {
26983
+ references.set(bindingId, (references.get(bindingId) ?? 0) + 1);
26984
+ };
26985
+ for (const node of Object.values(document.graph.nodes)) {
26986
+ if (!("inputs" in node)) continue;
26987
+ const inputs = Object.values(nodeInputMappings(node));
26988
+ for (const mapping of inputs) {
26989
+ if (mapping.kind != "sources") continue;
26990
+ for (const source of mapping.sources) if (source.kind == "binding") add(source.bindingId);
26991
+ }
26992
+ }
26993
+ return references;
26994
+ }
26995
+ function setConnectorConnection(content, nodeId, connectionId) {
26996
+ const node = content.document.graph.nodes[nodeId];
26997
+ if (node?.kind != "task" || !("executor" in node.task) || node.task.executor.kind != "connector") return;
26998
+ const task = node.task;
26999
+ if (task.executor.kind != "connector") return;
27000
+ if (task.executor.connectionId == connectionId) return [];
27001
+ const { connectionId: _, ...executor } = task.executor;
27002
+ return [{
27003
+ before: task,
27004
+ kind: "graph.node.task.set",
27005
+ nodeId,
27006
+ value: {
27007
+ ...task,
27008
+ executor: {
27009
+ ...executor,
27010
+ ...connectionId == null ? {} : { connectionId }
27011
+ }
27012
+ }
27013
+ }];
27014
+ }
27015
+ function updateTriggerConfig(content, nodeId, name, value) {
27016
+ const trigger = content.document.graph.nodes[nodeId];
27017
+ if (trigger == null || trigger.kind != "integration" && trigger.kind != "poll") return;
27018
+ const next = fixedInputValue(value);
27019
+ if (dequal(trigger.config[name], next)) return [];
27020
+ return [{
27021
+ before: trigger.config[name],
27022
+ kind: "graph.trigger.config.set",
27023
+ name,
27024
+ nodeId,
27025
+ value: next
27026
+ }];
27027
+ }
27028
+ function updateTriggerSchedule(content, nodeId, schedule) {
27029
+ const trigger = content.document.graph.nodes[nodeId];
27030
+ if (trigger == null) return;
27031
+ switch (trigger.kind) {
27032
+ case "cron": return dequal(trigger.cronTimes, schedule) ? [] : [{
27033
+ before: trigger.cronTimes,
27034
+ kind: "graph.trigger.schedule.set",
27035
+ nodeId,
27036
+ value: schedule
27037
+ }];
27038
+ case "poll": return dequal(trigger.pollTimes, schedule) ? [] : [{
27039
+ before: trigger.pollTimes,
27040
+ kind: "graph.trigger.schedule.set",
27041
+ nodeId,
27042
+ value: schedule
27043
+ }];
27044
+ case "integration":
27045
+ case "manual":
27046
+ case "webhook": return;
27047
+ default: return;
27048
+ }
27049
+ }
27050
+ function setTriggerConnection(content, nodeId, connectionId) {
27051
+ const trigger = content.document.graph.nodes[nodeId];
27052
+ if (trigger == null || trigger.kind != "poll" && trigger.kind != "integration") return;
27053
+ if (trigger.connectionId == connectionId) return [];
27054
+ return [{
27055
+ before: trigger.connectionId,
27056
+ kind: "graph.node.field.set",
27057
+ field: "connectionId",
27058
+ nodeId,
27059
+ value: connectionId
27060
+ }];
27061
+ }
27062
+ function defaultInputs(ports) {
27063
+ return Object.fromEntries(ports.flatMap((port) => "handle" in port && Object.hasOwn(port, "value") ? [[port.handle, {
27064
+ kind: "value",
27065
+ value: port.value
27066
+ }]] : []));
27067
+ }
27068
+ function llmInputValue(values, handle, fallback) {
27069
+ return values != null && Object.hasOwn(values, handle) ? values[handle] : fallback;
27070
+ }
27071
+ function setCodeActions(content, nodeId, capabilities) {
27072
+ const node = content.document.graph?.nodes[nodeId];
27073
+ if (node?.kind != "task" || !("moduleId" in node.task) || dequal(node.task.capabilities ?? [], capabilities)) return;
27074
+ return [{
27075
+ kind: "graph.node.task.capabilities.set",
27076
+ nodeId,
27077
+ before: node.task.capabilities,
27078
+ value: capabilities
27079
+ }];
27080
+ }
27081
+ function createDecisionTask(identity, name = "AI Decision", questions) {
27082
+ return createManagedTask(identity, decisionTask(questions, name));
27011
27083
  }
27012
27084
  //#endregion
27013
27085
  //#region src/workbench/browser/runtime/canvasPresentation.ts
@@ -39280,4 +39352,4 @@ function replaceTaskPorts(revision, nodeId, task, values) {
39280
39352
  return changes;
39281
39353
  }
39282
39354
  //#endregion
39283
- export { RunStore as $, setInputSources as $n, DropdownMenuSubContent as $t, datePickerValue as A, FeishuEventPicker as An, NativeScrollArea as At, CacheResource as B, providerIconAppearance as Bn, EmptyHeader as Bt, valueForEditor as C, zh_CN_default$3 as Cn, Popover as Ct, calendarChange as D, fr_default$3 as Dn, PopoverPanelContent as Dt, typeOfSchema as E, ja_default$3 as En, PopoverHeader as Et, feishuResourceKind as F, allConnectorConnectionsQuery as Fn, InputGroupAddon as Ft, semanticNodeIcon as G, securityOptions as Gn, DropdownMenuContent as Gt, resourceData as H, object as Hn, EmptyTitle as Ht, supportsFeishuChatFilter as I, decodeResultList as In, InputGroupInput as It, providerIcon as J, servers as Jn, DropdownMenuLabel as Jt, triggerNodeIcon as K, selectOperation as Kn, DropdownMenuGroup as Kt, combineSources as L, decodeTriggerCatalog as Ln, Empty as Lt, addNodeIntent as M, errorNotice as Mn, VirtualScrollArea as Mt, deriveAddNodeOptions as N, WorkbenchClient as Nn, Z as Nt, calendarDate as O, en_default$3 as On, PopoverTitle as Ot, indexAddNodeOptions as P, randomId as Pn, InputGroup as Pt, useIconifyData as Q, setConnectorConnection as Qn, DropdownMenuSub as Qt, mapSource as R, connection as Rn, EmptyContent as Rt, schemaForEditor as S, zh_TW_default$3 as Sn, followWorkbenchLink as St, isUnconstrainedSchema as T, ko_default$3 as Tn, PopoverDescription as Tt, resourceValue as U, openApiFieldIssues as Un, DropdownMenu as Ut, observeResource as V, listOperations as Vn, EmptyMedia as Vt, designerGraph as W, openApiTask as Wn, DropdownMenuCheckboxItem as Wt, IconifyProvider as X, resetInputValues as Xn, DropdownMenuRadioItem as Xt, ContentIcon as Y, repairNodeNames as Yn, DropdownMenuRadioGroup as Yt, useIconifyCollectionLoader as Z, setCodeActions as Zn, DropdownMenuSeparator as Zt, updateValue as _, SourceForm as _n, ApiError as _r, setComment as _t, nameCreatedNodes as a, MenuRoot as an, resolutionOutputPorts as ar, deriveInspectorDiagnostics as at, editorComponent as b, uiLocales as bn, useAriaLabelledBy as br, setNodePositions as bt, updateCondition as c, MenuPopup as cn, triggerOutputDefinitions as cr, diagnosticNodeId as ct, updateNodeName as d, ContextMenuRootContext as dn, triggerConfigValues as dr, connectionCatalog as dt, DropdownMenuSubTrigger as en, setTriggerConnection as er, canCancelRun as et, updateNodeSettings as f, useContextMenuRootContext as fn, inputValue as fr, canvasPresentationChange as ft, updateTaskPorts as g, EventSourcesPage as gn, string as gr, restoreCanvasPresentation as gt, updateTaskAdditionalInputs as h, Badge as hn, record$1 as hr, removeComments as ht, deleteSelection as i, useCompositeItem as in, replaceSource as ir, Latest as it, isDateFormat as j, EventSourceSetup as jn, ScrollArea as jt, datePickerChange as k, I18n as kn, PopoverTrigger as kt, updateNodeDescription as l, MenuItem as ln, isJsonObject as lr, schemaMismatchMessage as lt, updateTask as m, useMenuRootContext as mn, jsonValue as mr, flowPresentation as mt, agentTool as n, isElementDisabled as nn, updateTriggerSchedule as nr, revisionView as nt, setInputValue as o, MenuPositioner as on, sourceOutputLabel as or, diagnosticItems as ot, updateResolution as p, MenuRootContext as pn, invalidResponse as pr, commentIds as pt, actionSummary as q, serverAddress as qn, DropdownMenuItem as qt, applyFlowChanges as r, findRootOwnerId as rn, imports as rr, flowResourceReferences as rt, setInputVariable as s, MenuPortal as sn, sampleErrorOutputs as sr, diagnosticMessage as st, addNode as t, DropdownMenuTrigger as tn, updateTriggerConfig as tr, hasRunFilter as tt, updateNodeIcon as u, MenuGroup as un, triggerConfigValue as ur, actionWithConnections as ut, updateWebhook as v, SourceSelect as vn, controlErrorCode as vr, setFlowViewport as vt, getDefaultValue as w, ru_default$3 as wn, PopoverContent as wt, editorGroups as x, waitBranchDescription as xn, IconThemeContext as xr, IdTooltip as xt, defaultValueEditorSchema as y, createI18n as yn, Checkbox as yr, setNodeContentHidden as yt, scopedValue as z, connectorActionMetadata as zn, EmptyDescription as zt };
39355
+ export { RunStore as $, connection as $n, DropdownMenuContent as $t, datePickerValue as A, zh_TW_default$3 as An, followWorkbenchLink as At, CacheResource as B, errorNotice as Bn, VirtualScrollArea as Bt, valueForEditor as C, Badge as Cn, setCodeActions as Ct, calendarChange as D, createI18n as Dn, updateTriggerConfig as Dt, typeOfSchema as E, SourceSelect as En, setTriggerConnection as Et, feishuResourceKind as F, fr_default$3 as Fn, PopoverPanelContent as Ft, semanticNodeIcon as G, decodeTriggerCatalog as Gn, Empty as Gt, resourceData as H, randomId as Hn, InputGroup as Ht, supportsFeishuChatFilter as I, en_default$3 as In, PopoverTitle as It, providerIcon as J, sampleErrorOutputs as Jn, EmptyHeader as Jt, triggerNodeIcon as K, resolutionOutputPorts as Kn, EmptyContent as Kt, combineSources as L, I18n as Ln, PopoverTrigger as Lt, addNodeIntent as M, ru_default$3 as Mn, PopoverContent as Mt, deriveAddNodeOptions as N, ko_default$3 as Nn, PopoverDescription as Nt, calendarDate as O, uiLocales as On, updateTriggerSchedule as Ot, indexAddNodeOptions as P, ja_default$3 as Pn, PopoverHeader as Pt, useIconifyData as Q, triggerConfigValues as Qn, DropdownMenuCheckboxItem as Qt, mapSource as R, FeishuEventPicker as Rn, NativeScrollArea as Rt, schemaForEditor as S, useMenuRootContext as Sn, resetInputValues as St, isUnconstrainedSchema as T, SourceForm as Tn, setInputSources as Tt, resourceValue as U, allConnectorConnectionsQuery as Un, InputGroupAddon as Ut, observeResource as V, WorkbenchClient as Vn, Z as Vt, designerGraph as W, decodeResultList as Wn, InputGroupInput as Wt, IconifyProvider as X, isJsonObject as Xn, EmptyTitle as Xt, ContentIcon as Y, triggerOutputDefinitions as Yn, EmptyMedia as Yt, useIconifyCollectionLoader as Z, triggerConfigValue as Zn, DropdownMenu as Zt, updateValue as _, MenuItem as _n, Checkbox as _r, setComment as _t, nameCreatedNodes as a, DropdownMenuSeparator as an, openApiTask as ar, deriveInspectorDiagnostics as at, editorComponent as b, useContextMenuRootContext as bn, setNodePositions as bt, updateCondition as c, DropdownMenuSubTrigger as cn, serverAddress as cr, diagnosticNodeId as ct, updateNodeName as d, findRootOwnerId as dn, invalidResponse as dr, connectionCatalog as dt, DropdownMenuGroup as en, connectorActionMetadata as er, canCancelRun as et, updateNodeSettings as f, useCompositeItem as fn, jsonValue as fr, canvasPresentationChange as ft, updateTaskPorts as g, MenuPopup as gn, controlErrorCode as gr, restoreCanvasPresentation as gt, updateTaskAdditionalInputs as h, MenuPortal as hn, ApiError as hr, removeComments as ht, deleteSelection as i, DropdownMenuRadioItem as in, openApiFieldIssues as ir, Latest as it, isDateFormat as j, zh_CN_default$3 as jn, Popover as jt, datePickerChange as k, waitBranchDescription as kn, IdTooltip as kt, updateNodeDescription as l, DropdownMenuTrigger as ln, servers as lr, schemaMismatchMessage as lt, updateTask as m, MenuPositioner as mn, string as mr, flowPresentation as mt, agentTool as n, DropdownMenuLabel as nn, listOperations as nr, revisionView as nt, setInputValue as o, DropdownMenuSub as on, securityOptions as or, diagnosticItems as ot, updateResolution as p, MenuRoot as pn, record$1 as pr, commentIds as pt, actionSummary as q, sourceOutputLabel as qn, EmptyDescription as qt, applyFlowChanges as r, DropdownMenuRadioGroup as rn, object as rr, flowResourceReferences as rt, setInputVariable as s, DropdownMenuSubContent as sn, selectOperation as sr, diagnosticMessage as st, addNode as t, DropdownMenuItem as tn, providerIconAppearance as tr, hasRunFilter as tt, updateNodeIcon as u, isElementDisabled as un, inputValue as ur, actionWithConnections as ut, updateWebhook as v, MenuGroup as vn, useAriaLabelledBy as vr, setFlowViewport as vt, getDefaultValue as w, EventSourcesPage as wn, setConnectorConnection as wt, editorGroups as x, MenuRootContext as xn, repairNodeNames as xt, defaultValueEditorSchema as y, ContextMenuRootContext as yn, IconThemeContext as yr, setNodeContentHidden as yt, scopedValue as z, EventSourceSetup as zn, ScrollArea as zt };