@burdenoff/fluidgrids-fe-sdk 2026.1111.14 → 2026.1111.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/dist/{ExecutionDetailPage-itor_whl.js → ExecutionDetailPage-DO38vZ_F.js} +4 -4
- package/dist/{FluidGridsProvider-B30VcLdX.js → FluidGridsProvider-B9RR_CI_.js} +2 -309
- package/dist/{HistoryPage-DueEld8g.js → HistoryPage-CA42pU85.js} +1 -1
- package/dist/{InsightsPage-DQ7KCR9h.js → InsightsPage-CBoN_Mj9.js} +2 -2
- package/dist/{ManagedAiPolicyAuthority-C0YPTJMS.js → ManagedAiPolicyAuthority-CKihmbJE.js} +2 -2
- package/dist/{MissingNodesInstallModal-Cj31oMDX.js → MissingNodesInstallModal-Dm0nMBXM.js} +1 -1
- package/dist/{TemplateConfigurationModal-BAPCG8y-.js → TemplateConfigurationModal-Bs_V-E4u.js} +1 -1
- package/dist/{TemplateDetailPanel-CZ1uxEQL.js → TemplateDetailPanel-MlT39VLG.js} +1 -1
- package/dist/{TemplatesPage-DWdgZnIH.js → TemplatesPage-CHVpWBuw.js} +5 -4
- package/dist/{WorkflowSearchRedirect-C8vhSZK9.js → WorkflowSearchRedirect-3gyHcYY2.js} +13 -9
- package/dist/{WorkflowShareDialog-DnBQA3V6.js → WorkflowShareDialog-0Ai1HED-.js} +2 -1
- package/dist/{WorkflowsList-74jjJFsJ.js → WorkflowsList-CJ3KmMHX.js} +5 -4
- package/dist/agent-tools.d.ts +3 -0
- package/dist/agent-tools.js +5 -0
- package/dist/{agentTools-D5AW7zHn.js → agentTools-B1IK1JEO.js} +2 -2
- package/dist/{canvasNoteTools-BqQTTCll.js → canvasNoteTools-eewVHVuy.js} +3 -2
- package/dist/executions.js +1 -1
- package/dist/{flow-builder-BR8p5tXG.js → flow-builder-C_3sY3pZ.js} +12 -157
- package/dist/fluidgridsEvents-CNdcrUNN.js +310 -0
- package/dist/history.js +1 -1
- package/dist/index-CHeY7_A1.d.ts +105 -0
- package/dist/{index-CLqh2u28.d.ts → index-DRf25-D3.d.ts} +7 -105
- package/dist/index.d.ts +3 -2
- package/dist/index.js +21 -946
- package/dist/marksStore-DGCXjTmZ.js +151 -0
- package/dist/{node-detail-view-Dnhqdn8C.js → node-detail-view-CAws5qjg.js} +3 -3
- package/dist/observability.d.ts +1 -1
- package/dist/observability.js +1 -1
- package/dist/{quick-config-panel-C4tSpCrt.js → quick-config-panel-DOzNkSVV.js} +2 -2
- package/dist/settings.js +1 -1
- package/dist/templates.js +1 -1
- package/dist/uiMarkTools-nlmzsHQM.js +937 -0
- package/dist/{useExecutions-CNEN1ENQ.js → useExecutions-DkS0FTfw.js} +2 -1
- package/dist/{useObservability-CmFFXmKb.js → useObservability-BkxhHZsX.js} +2 -1
- package/dist/{useRunHistory-DhU_mrzF.js → useRunHistory-DHehG09Z.js} +1 -1
- package/dist/{useWorkflows-D01LC39Y.js → useWorkflows-DyhtoVwp.js} +25 -5
- package/dist/workflow-builder.js +2 -2
- package/dist/workflow-route.d.ts +33 -0
- package/dist/workflow-route.js +4 -0
- package/dist/workflowRouteData-BkfVOc-O.js +169 -0
- package/dist/workflows-list.js +1 -1
- package/package.json +9 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { At as useSaveStatusStore, J as paramsFromOperation, K as nodeTitle, L as createConfiguredNode, W as fixedParameterState, Y as selectedOperationOf, _ as registryNodeData, f as isNodeConfigsInitialized, o as NODE_CONFIGS, pt as autosaveAllowedFor, xt as isFlowComplete } from "./FluidGridsProvider-
|
|
2
|
+
import { At as useSaveStatusStore, J as paramsFromOperation, K as nodeTitle, L as createConfiguredNode, W as fixedParameterState, Y as selectedOperationOf, _ as registryNodeData, f as isNodeConfigsInitialized, o as NODE_CONFIGS, pt as autosaveAllowedFor, xt as isFlowComplete } from "./FluidGridsProvider-B9RR_CI_.js";
|
|
3
3
|
import { E as resolveOutputHandles, H as useFlowStore, T as resolveInputHandles } from "./node-operation-selection--oy-yEq_.js";
|
|
4
|
-
import {
|
|
4
|
+
import { Et as isNodeTypeHiddenFromPalette, N as computeAttachPosition } from "./flow-builder-C_3sY3pZ.js";
|
|
5
5
|
import { AgentToolError, defineAgentTool } from "@burdenoff/fe-libs/shared/agent-tools";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import { J as paramsFromOperation, K as nodeTitle, Y as selectedOperationOf } from "./FluidGridsProvider-
|
|
2
|
+
import { n as useAgentMarksStore, r as toPlainText } from "./marksStore-DGCXjTmZ.js";
|
|
3
|
+
import { J as paramsFromOperation, K as nodeTitle, Y as selectedOperationOf } from "./FluidGridsProvider-B9RR_CI_.js";
|
|
4
4
|
import { H as useFlowStore } from "./node-operation-selection--oy-yEq_.js";
|
|
5
|
+
import { g as notesKeyOf } from "./flow-builder-C_3sY3pZ.js";
|
|
5
6
|
import { AgentToolError, defineAgentTool } from "@burdenoff/fe-libs/shared/agent-tools";
|
|
6
7
|
import { z } from "zod";
|
|
7
8
|
|
package/dist/executions.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as ExecutionDetailPage, y as ExecutionsListPage } from "./ExecutionDetailPage-
|
|
2
|
+
import { t as ExecutionDetailPage, y as ExecutionsListPage } from "./ExecutionDetailPage-DO38vZ_F.js";
|
|
3
3
|
|
|
4
4
|
export { ExecutionDetailPage, ExecutionsListPage };
|
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { A as nodeAccent, B as NODE_TYPE_DRAG_DATA_FORMAT, G as isTriggerOperation, H as useFlowStore, M as isImageIcon, T as resolveInputHandles, U as useIsValidConnection, V as STICKY_NOTE_TYPE, g as toCodeMirrorDiagnostics, j as NodeTypeIcon, r as CODE_WORKFLOW_NODE_TYPE, z as NODE_OPERATION_DRAG_DATA_FORMAT } from "./node-operation-selection--oy-yEq_.js";
|
|
3
|
-
import { $ as isStringOptionList, $
|
|
3
|
+
import { $ as isStringOptionList, $t as inAppLeaveTarget, A as StoreNodeProductsByTypeDocument, At as useSaveStatusStore, B as useRunGuard, Bn as connectionsForAdapter, Bt as shouldReleaseForIdle, C as GetMyNodeInstallationsDocument, Ct as useSaveWorkflow, D as InstallWorkflowNodeDocument, E as InstallPurchasedNodeDocument, En as FLUIDGRIDS_FLAGS, F as getNodeMetadata, Ft as leaseCallQueue, G as nodeSubtitle, Gn as getNodeDetail, Gt as sessionBeforeReload, H as asRecord, Hn as matchesAdapterProvider, Ht as EDIT_SESSION_ID, I as buildOperationSeed, In as usePaletteGates, It as leaseCallSequence, J as paramsFromOperation, Jn as useBuilderReadOnly, Jt as AUTOSAVE_DEBOUNCE_MS, K as nodeTitle, Kn as buildStickyNode, Kt as rememberOwnStatusChange, Ln as usePhaseCFlags, Lt as phaseAfterAcquire, M as UninstallOrganizationPrivateNodeDocument, Mn as useDurableFunctionNodesEnabled, Mt as useEditLeaseStore, N as UninstallWorkflowNodeDocument, Nn as useDurableParityEnabled, Nt as bannerOf, Ot as refusalOfQuota, Pn as useFluidGridsFlag, Pt as isLocked, R as useInsertNode, Rt as phaseAfterTakeOver, S as CreateStoreOrderDocument, St as useFlowValidator, T as InstallOrganizationPrivateNodeDocument, U as coerceNumber, Un as newConnectionProviderKey, Ut as forgetSessionForReload, V as workflowParameterIssues, Vn as isOptionalAdapter, Vt as tickAction, Wn as replaceAdapterConnections, Wt as rememberSessionForReload, X as useNodeConfig, Xn as getGlobalStoreClient, Xt as canAutosave, Yt as AUTOSAVE_RETRY_DELAYS_MS, _n as loadDefinitionJson, _t as leavingLosesChanges, a as NODES_METADATA, at as casesFromRules, b as BrowseWorkflowNodesDocument, bt as watchLeavingLosesChanges, c as ensureInstalledNodeTypesLoaded, cn as structuredParameterType, d as ensureRegistryNodeTypesLoaded, dn as isParamVisible, dt as useGuardedNavigate, en as saveFailureActionOf, et as optionListText, f as isNodeConfigsInitialized, fn as useFluidGridsAnalytics, ft as useManualSave, g as registerWorkflowNodeTypes, gt as editingLeaseLocked, hn as useNodeRegistryRevision, ht as editStateFor, i as AVAILABLE_NODES, it as SwitchRulesEditor, jt as useEditLeaseLocked, k as OrganizationPrivateNodesDocument, kt as saveIndicatorOf, l as ensureNodeConfigsLoaded, lt as boundFieldsOf, m as refetchStoreNodes, mn as useCanvasEdges, mt as departingSave, nn as useNodeExecution, nt as resolveLoadOptionsSpec, o as NODE_CONFIGS, on as formatParameterValue, ot as FieldTree, p as onNodeTypesUpdate, pn as openRunQuotaUpgradePrompt, pt as autosaveAllowedFor, q as optionText, qn as BuilderReadOnlyProvider, qt as rememberRevision, rt as ConditionTreeBuilder, s as NODE_TYPES, sn as parseParameterValue, st as parseMappingValue, t as FluidGridsContext, tn as workflowFingerprint, tt as optionListValues, ut as missingRequiredParameters, v as scheduleNodePaletteLoad, vt as savedEverythingBeforeLeaving, w as GetNodeInstallableVersionsDocument, x as BrowseWorkflowTemplatesDocument, xt as isFlowComplete, yt as touchesSavedFields, z as MissingParametersDialog, zn as useWorkflowTestsEnabled, zt as releasesOnClose } from "./FluidGridsProvider-B9RR_CI_.js";
|
|
4
4
|
import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
|
|
5
5
|
import { Bi as describeOperationError, Br as WorkflowGitRepositoryDocument, Ct as LinkWorkflowGitRepositoryDocument, Dr as WorkflowDefinitionDocument, Ei as WorkspaceRunsQuotaDocument, Ht as PreviewScheduleDocument, Ir as WorkflowGenerationTemplatesDocument, J as DeleteWorkflowRolloutDocument, Kt as PushWorkflowToGitDocument, Li as emitFluidGridsEvent, Lr as WorkflowGitCommitsDocument, Mt as NodeSchemaIntrospectionDocument, Ni as waitForFluidGridsClient, Nr as WorkflowEnvironmentsDocument, Oi as getFluidGridsClient, Pt as NodeUsageStatusDocument, Qt as RemoveNodeFromWorkflowsDocument, Rr as WorkflowGitDiffDocument, Si as WorkflowVersioningDocument, Ui as throwIfResultError, Vn as TakeOverWorkflowEditLeaseDocument, Wr as WorkflowPromotionRequestsDocument, Xn as UnlinkWorkflowGitRepositoryDocument, Yt as RejectWorkflowPromotionDocument, Z as DeployWorkflowVersionToDevDocument, Zt as ReleaseWorkflowEditLeaseDocument, cr as UpdateWorkflowEnvironmentPolicyDocument, i as ActivateWorkflowVersionCheckedDocument, jn as SetWorkflowRolloutDocument, jr as WorkflowEditLeaseDocument, ki as getFluidGridsClientSafe, mr as WebhookTestListenerDocument, n as AcquireWorkflowEditLeaseDocument, nn as RequestWorkflowPromotionDocument, oa as __exportAll, on as RestoreWorkflowFromGitDocument, qi as getFluidGridsConfig, u as ApproveWorkflowPromotionDocument, wr as WorkflowCallInputsDocument, wt as ListenForWebhookTestEventDocument, x as CancelWorkflowPromotionDocument, xi as WorkflowVersionDrainageDocument, yr as WorkflowAuthoringDocument, zn as StopWebhookTestListenerDocument, zr as WorkflowGitPushesDocument } from "./node-endpoint-configs-DHFGA5MQ.js";
|
|
6
6
|
import { D as describeSchedule, H as pauseSchedule, _ as useResource, c as FieldError, d as NativeSelect, et as triggerSchedule, nt as unpauseSchedule, p as StatusPill, r as describeRule, s as isAgentNodeType, v as backfillSchedule } from "./agent-form-BvMWhQ42.js";
|
|
7
7
|
import { CF as WorkflowExportFormat, Eo as CodeReplaceStatus, PD as ScheduleType, QF as WorkflowTestExpectedStatus, SF as WorkflowEnvironment, VF as WorkflowScheduleOverlapPolicy, hI as FLUIDGRIDS_PERMISSIONS, vI as SdkPermissionButton, xI as useFluidGridsPermission, xu as DrainageStatus, yI as SdkPermissionGate, yP as VersioningBehavior } from "./graphql-types-XcDLtFwU.js";
|
|
8
8
|
import { a as useConnections, r as useAgentsUsingConnection, t as useAgentDefinitionList, wt as useRunFromNodeEligibilityQuery } from "./useAgentDefinitions-NFtLytDR.js";
|
|
9
|
+
import { a as emitTemplateUsed, f as BILLING_PLANS_PATH, g as collectExtensions, m as RUNS_QUOTA_NAME, o as emitUpgradeClicked, s as emitWorkflowCreated, t as emitNodeInstalled, y as isQuotaExhaustedFailure } from "./fluidgridsEvents-CNdcrUNN.js";
|
|
9
10
|
import { F as normaliseAssertRules, I as operatorSpec, L as readAssertRulesSetting, M as ASSERT_OPERATORS, N as describeAssertRuleProblem, P as emptyAssertRuleRow, R as rowsFromRules, _ as buildNodeDisplayMap, a as TEST_STATUS_TONE_CLASS, b as EntityTagPicker, c as draftToInput, d as isTestRunOpen, f as nextSortOrder, g as testStatusTone, h as testStatusLabel, i as useWorkflowTests, l as emptyTestCaseDraft, m as testRunSummaryText, n as useWorkflowProposal, p as pinnedOutputsFromCanvas, s as draftFromTestCase, t as WorkflowProposalCard, u as enabledCaseIds, z as ruleFromRow } from "./WorkflowProposalCard-8Vr56kQa.js";
|
|
10
11
|
import { t as cn$1 } from "./cn-QqidFIgr.js";
|
|
11
12
|
import { i as Button$2, t as PublishCustomNodeAction } from "./PublishCustomNodeAction-D2F7oN0S.js";
|
|
12
|
-
import {
|
|
13
|
+
import { n as useAgentMarksStore } from "./marksStore-DGCXjTmZ.js";
|
|
14
|
+
import { O as CreateWorkflowRefusalDialog, b as lineOfNode, h as fileBaseName, i as useWorkflowCodeExport, n as downloadWorkflowCodeExport, t as WorkflowShareDialog, v as isLosslessReport, w as sortFidelityItems, x as orderedExportFiles, y as isLossyFidelityItem } from "./WorkflowShareDialog-0Ai1HED-.js";
|
|
13
15
|
import { t as FluidGridsDocsLink } from "./FluidGridsDocsLink-JxkBpOeb.js";
|
|
14
|
-
import { a as useDeactivateWorkflow, d as useRestoreWorkflowVersion, o as useDeleteWorkflow, t as useActivateWorkflow, v as useWorkflowVersions } from "./useWorkflows-
|
|
16
|
+
import { a as useDeactivateWorkflow, d as useRestoreWorkflowVersion, o as useDeleteWorkflow, t as useActivateWorkflow, v as useWorkflowVersions } from "./useWorkflows-DyhtoVwp.js";
|
|
15
17
|
import { n as VersionLifecycleBar, r as countLifecycle, t as VersionDiffDialog } from "./VersionDiffDialog-Dq2xlPFI.js";
|
|
16
18
|
import { n as useRequestedProposal } from "./useRequestedProposal-B7uPXfZB.js";
|
|
17
19
|
import { t as AiCreditBalanceSlot } from "./aiCreditsBridge-BuE92tKo.js";
|
|
@@ -10572,7 +10574,7 @@ function buildNodeCheck(requiredNodeTypes, installedAppIds) {
|
|
|
10572
10574
|
}
|
|
10573
10575
|
|
|
10574
10576
|
// src/hooks/store/useTemplateImportFlow.tsx
|
|
10575
|
-
const LazyTemplateConfigurationModal = lazy(() => import("./TemplateConfigurationModal-
|
|
10577
|
+
const LazyTemplateConfigurationModal = lazy(() => import("./TemplateConfigurationModal-Bs_V-E4u.js").then((m) => ({ default: m.TemplateConfigurationModal })));
|
|
10576
10578
|
/**
|
|
10577
10579
|
* "Use this template", the same everywhere it is offered: the builder's
|
|
10578
10580
|
* template panel, the Templates page and the template preview page
|
|
@@ -12749,7 +12751,7 @@ function TemplatesGrid({ templates, loading, hasMore, onLoadMore, onTemplateClic
|
|
|
12749
12751
|
}
|
|
12750
12752
|
|
|
12751
12753
|
// src/builder/components/flow-builder/components/templates/TemplatesModal.tsx
|
|
12752
|
-
const LazyTemplateDetailPanel = lazy(() => import("./TemplateDetailPanel-
|
|
12754
|
+
const LazyTemplateDetailPanel = lazy(() => import("./TemplateDetailPanel-MlT39VLG.js").then((m) => ({ default: m.TemplateDetailPanel })));
|
|
12753
12755
|
/**
|
|
12754
12756
|
* Modal for browsing and selecting workflow templates
|
|
12755
12757
|
* Features:
|
|
@@ -20692,153 +20694,6 @@ function WebhookRunFollower() {
|
|
|
20692
20694
|
return null;
|
|
20693
20695
|
}
|
|
20694
20696
|
|
|
20695
|
-
// src/agentMarks/plainText.ts
|
|
20696
|
-
/**
|
|
20697
|
-
* ★ BOFF-11584: the text of a callout or note is model output, and the model
|
|
20698
|
-
* has read workflow content people wrote. It is shown as plain text only:
|
|
20699
|
-
* React renders it as a text node (never `dangerouslySetInnerHTML`, never a
|
|
20700
|
-
* markdown renderer), so markup, links and images in it stay inert characters.
|
|
20701
|
-
*
|
|
20702
|
-
* This keeps it short and printable as well: control characters (other than
|
|
20703
|
-
* line breaks) and bidirectional controls, which can disguise what a line
|
|
20704
|
-
* says, are removed; runs of blank lines collapse; the result is clamped.
|
|
20705
|
-
*/
|
|
20706
|
-
const BIDI_CONTROLS = /* @__PURE__ */ new Set([
|
|
20707
|
-
1564,
|
|
20708
|
-
8206,
|
|
20709
|
-
8207,
|
|
20710
|
-
8234,
|
|
20711
|
-
8235,
|
|
20712
|
-
8236,
|
|
20713
|
-
8237,
|
|
20714
|
-
8238,
|
|
20715
|
-
8294,
|
|
20716
|
-
8295,
|
|
20717
|
-
8296,
|
|
20718
|
-
8297
|
|
20719
|
-
]);
|
|
20720
|
-
function isDroppedCharacter(code) {
|
|
20721
|
-
if (code === 10) return false;
|
|
20722
|
-
if (code <= 31) return true;
|
|
20723
|
-
if (code >= 127 && code <= 159) return true;
|
|
20724
|
-
return BIDI_CONTROLS.has(code);
|
|
20725
|
-
}
|
|
20726
|
-
function toPlainText(text, max) {
|
|
20727
|
-
let kept = "";
|
|
20728
|
-
for (const character of text.replace(/\r\n?/g, "\n").replace(/\t/g, " ")) if (!isDroppedCharacter(character.codePointAt(0) ?? 0)) kept += character;
|
|
20729
|
-
const cleaned = kept.replace(/ {2,}/g, " ").replace(/ *\n */g, "\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
20730
|
-
if (cleaned.length <= max) return cleaned;
|
|
20731
|
-
return `${cleaned.slice(0, max - 1).trimEnd()}…`;
|
|
20732
|
-
}
|
|
20733
|
-
|
|
20734
|
-
// src/agentMarks/marksStore.ts
|
|
20735
|
-
/** The text of a mark is model output: kept as plain text, never markup. */
|
|
20736
|
-
const CALLOUT_LABEL_MAX = 200;
|
|
20737
|
-
const NOTE_MESSAGE_MAX = 280;
|
|
20738
|
-
/** A workflow holds at most this many notes, resolved ones included. */
|
|
20739
|
-
const MAX_NOTES_PER_WORKFLOW = 20;
|
|
20740
|
-
let sequence = 0;
|
|
20741
|
-
const nextId = (prefix) => {
|
|
20742
|
-
sequence += 1;
|
|
20743
|
-
return `${prefix}${sequence}`;
|
|
20744
|
-
};
|
|
20745
|
-
const useAgentMarksStore = create()((set, get) => ({
|
|
20746
|
-
callouts: [],
|
|
20747
|
-
notes: [],
|
|
20748
|
-
nextNumber: {},
|
|
20749
|
-
openNoteId: null,
|
|
20750
|
-
flash: null,
|
|
20751
|
-
actions: {
|
|
20752
|
-
addCallout: ({ label, target, element, route }) => {
|
|
20753
|
-
const callout = {
|
|
20754
|
-
id: nextId("c"),
|
|
20755
|
-
label: toPlainText(label, 200),
|
|
20756
|
-
target,
|
|
20757
|
-
route,
|
|
20758
|
-
element: element ? new WeakRef(element) : null
|
|
20759
|
-
};
|
|
20760
|
-
set((state) => ({ callouts: [...state.callouts, callout].slice(-3) }));
|
|
20761
|
-
return callout;
|
|
20762
|
-
},
|
|
20763
|
-
rebindCallout: (id, element) => set((state) => ({ callouts: state.callouts.map((callout) => callout.id === id ? {
|
|
20764
|
-
...callout,
|
|
20765
|
-
element: new WeakRef(element)
|
|
20766
|
-
} : callout) })),
|
|
20767
|
-
removeCallout: (id) => set((state) => ({ callouts: state.callouts.filter((callout) => callout.id !== id) })),
|
|
20768
|
-
clearCallouts: () => {
|
|
20769
|
-
const count = get().callouts.length;
|
|
20770
|
-
if (count > 0) set({ callouts: [] });
|
|
20771
|
-
return count;
|
|
20772
|
-
},
|
|
20773
|
-
dropCalloutsOffRoute: (route) => {
|
|
20774
|
-
const { callouts } = get();
|
|
20775
|
-
const kept = callouts.filter((callout) => callout.route === route);
|
|
20776
|
-
if (kept.length !== callouts.length) set({ callouts: kept });
|
|
20777
|
-
return callouts.length - kept.length;
|
|
20778
|
-
},
|
|
20779
|
-
addNote: (input) => {
|
|
20780
|
-
const { notes, nextNumber } = get();
|
|
20781
|
-
if (notes.filter((note) => note.workflowKey === input.workflowKey).length >= 20) return null;
|
|
20782
|
-
const number = nextNumber[input.workflowKey] ?? 1;
|
|
20783
|
-
const note = {
|
|
20784
|
-
id: nextId("n"),
|
|
20785
|
-
number,
|
|
20786
|
-
workflowKey: input.workflowKey,
|
|
20787
|
-
nodeId: input.nodeId,
|
|
20788
|
-
nodeLabel: toPlainText(input.nodeLabel, 80),
|
|
20789
|
-
paramKey: input.paramKey ?? null,
|
|
20790
|
-
kind: input.kind,
|
|
20791
|
-
message: toPlainText(input.message, 280),
|
|
20792
|
-
resolved: false
|
|
20793
|
-
};
|
|
20794
|
-
set({
|
|
20795
|
-
notes: [...notes, note],
|
|
20796
|
-
nextNumber: {
|
|
20797
|
-
...nextNumber,
|
|
20798
|
-
[input.workflowKey]: number + 1
|
|
20799
|
-
}
|
|
20800
|
-
});
|
|
20801
|
-
return note;
|
|
20802
|
-
},
|
|
20803
|
-
setResolved: (id, resolved) => set((state) => ({ notes: state.notes.map((note) => note.id === id ? {
|
|
20804
|
-
...note,
|
|
20805
|
-
resolved
|
|
20806
|
-
} : note) })),
|
|
20807
|
-
removeNote: (id) => set((state) => ({
|
|
20808
|
-
notes: state.notes.filter((note) => note.id !== id),
|
|
20809
|
-
openNoteId: state.openNoteId === id ? null : state.openNoteId
|
|
20810
|
-
})),
|
|
20811
|
-
clearNotes: (workflowKey) => {
|
|
20812
|
-
const { notes, openNoteId } = get();
|
|
20813
|
-
const kept = workflowKey === void 0 ? [] : notes.filter((note) => note.workflowKey !== workflowKey);
|
|
20814
|
-
const removed = notes.length - kept.length;
|
|
20815
|
-
if (removed > 0) set({
|
|
20816
|
-
notes: kept,
|
|
20817
|
-
openNoteId: kept.some((note) => note.id === openNoteId) ? openNoteId : null
|
|
20818
|
-
});
|
|
20819
|
-
return removed;
|
|
20820
|
-
},
|
|
20821
|
-
openNote: (id) => set({ openNoteId: id }),
|
|
20822
|
-
flashNode: (nodeId) => {
|
|
20823
|
-
sequence += 1;
|
|
20824
|
-
set({ flash: {
|
|
20825
|
-
nodeId,
|
|
20826
|
-
token: sequence
|
|
20827
|
-
} });
|
|
20828
|
-
}
|
|
20829
|
-
}
|
|
20830
|
-
}));
|
|
20831
|
-
/** Reset everything (tests, and sign-out if a host wants it). */
|
|
20832
|
-
function resetAgentMarks() {
|
|
20833
|
-
useAgentMarksStore.setState({
|
|
20834
|
-
callouts: [],
|
|
20835
|
-
notes: [],
|
|
20836
|
-
nextNumber: {},
|
|
20837
|
-
openNoteId: null,
|
|
20838
|
-
flash: null
|
|
20839
|
-
});
|
|
20840
|
-
}
|
|
20841
|
-
|
|
20842
20697
|
// src/builder/agentNotes/notesKey.ts
|
|
20843
20698
|
/**
|
|
20844
20699
|
* ★ BOFF-11584: which workflow a canvas note belongs to. A saved workflow is
|
|
@@ -27575,8 +27430,8 @@ function EditLeaseBanner() {
|
|
|
27575
27430
|
}
|
|
27576
27431
|
|
|
27577
27432
|
// src/builder/components/flow-builder/flow-builder.tsx
|
|
27578
|
-
const LazyNodeDetailView = lazy(() => import("./node-detail-view-
|
|
27579
|
-
const LazyQuickConfigPanel = lazy(() => import("./quick-config-panel-
|
|
27433
|
+
const LazyNodeDetailView = lazy(() => import("./node-detail-view-CAws5qjg.js").then((m) => ({ default: m.NodeDetailView })));
|
|
27434
|
+
const LazyQuickConfigPanel = lazy(() => import("./quick-config-panel-DOzNkSVV.js").then((m) => ({ default: m.QuickConfigPanel })));
|
|
27580
27435
|
const edgeTypes = { deletable: CustomDeletableEdge };
|
|
27581
27436
|
const edgeOptions = {
|
|
27582
27437
|
type: "deletable",
|
|
@@ -27636,7 +27491,7 @@ const FlowBuilder = ({ readOnly = false }) => {
|
|
|
27636
27491
|
const [agentTools, setAgentTools] = useState([]);
|
|
27637
27492
|
useEffect(() => {
|
|
27638
27493
|
let cancelled = false;
|
|
27639
|
-
import("./agentTools-
|
|
27494
|
+
import("./agentTools-B1IK1JEO.js").then(({ createBuilderAgentTools }) => {
|
|
27640
27495
|
if (cancelled) return;
|
|
27641
27496
|
setAgentTools(createBuilderAgentTools({ durableFunctionsEnabled: () => paletteGatesRef.current }));
|
|
27642
27497
|
}).catch((error) => {
|
|
@@ -27691,7 +27546,7 @@ const FlowBuilder = ({ readOnly = false }) => {
|
|
|
27691
27546
|
const [noteTools, setNoteTools] = useState([]);
|
|
27692
27547
|
useEffect(() => {
|
|
27693
27548
|
let cancelled = false;
|
|
27694
|
-
import("./canvasNoteTools-
|
|
27549
|
+
import("./canvasNoteTools-eewVHVuy.js").then(({ createCanvasNoteTools }) => {
|
|
27695
27550
|
if (cancelled) return;
|
|
27696
27551
|
setNoteTools(createCanvasNoteTools({ focusNode: (nodeId) => fitViewRef.current({
|
|
27697
27552
|
nodes: [{ id: nodeId }],
|
|
@@ -27999,4 +27854,4 @@ const FlowBuilderPage = ({ workflow, readOnly = false }) => {
|
|
|
27999
27854
|
] });
|
|
28000
27855
|
};
|
|
28001
27856
|
|
|
28002
|
-
export {
|
|
27857
|
+
export { Popover$1 as $, DialogPortal as A, useInstalledNodes as B, Dialog$1 as C, WORKFLOW_TEST_NODE_TYPES as Ct, DialogFooter$1 as D, isRunControlNodeType as Dt, DialogDescription$1 as E, isNodeTypeHiddenFromPalette as Et, buildNodeCheck as F, RunnerStatusPill as G, NodeEditorTabBody as H, buildRequiredNodeTypes as I, useRunnerActions as J, RUNNER_INSTALL_SCRIPT_URL as K, getWorkflowNodeTypes as L, DialogTrigger$1 as M, computeAttachPosition as N, DialogHeader$1 as O, useTemplateImportFlow as P, NDV_Z_INDEX as Q, useImportWorkflowTemplate as R, badgeVariants as S, RUN_CONTROL_NODE_TYPES as St, DialogContent$1 as T, isDurableFunctionNodeType as Tt, NodeSettingsPanel as U, NodeExecutionActions as V, RunOnSection as W, NodeParamsForm as X, useRunners as Y, useGlobalStoreClient as Z, JsonView as _, CardFooter as _t, useAiWorkflowTemplates as a, ReadOnlyFieldset as at, templatePreview as b, Input$1 as bt, RunsUsageMeter as c, SchedulePanel as ct, readRunsQuota as d, NodeInputFields as dt, PopoverContent$1 as et, runsQuotaLevel as f, useNodeSelectedEvent as ft, notesKeyOf as g, CardDescription$1 as gt, useWorkflowReloadStore as h, CardContent$1 as ht, enrichDraftNodes as i, ConnectionFormDialog as it, DialogTitle$1 as j, DialogOverlay as k, RunsUsageMeterView as l, NodeEditorTabs as lt, releaseLeaseKeptForReload as m, Card$1 as mt, AI_DRAFT_MAX_PROMPT_LENGTH as n, CodeEditorField as nt, BUILDER_FULLSCREEN_ATTRIBUTE as o, useNodeEditorTab as ot, summarizeRunsQuota as p, FluidGridsMark as pt, runnerInstallCommand as q, draftToCanvas as r, ConnectionSelector as rt, BUILDER_FULLSCREEN_EVENT as s, SCHEDULE_NODE_TYPE as st, FlowBuilderPage as t, PopoverTrigger$1 as tt, useRunsQuota as u, TabButton as ut, TableView as v, CardHeader$1 as vt, DialogClose as w, filterPaletteNodes as wt, Badge$1 as x, DURABLE_FUNCTION_NODE_TYPES as xt, TemplateCard as y, CardTitle$1 as yt, useWorkflowTemplates as z };
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/billing/quota.ts
|
|
3
|
+
/**
|
|
4
|
+
* Plan-quota refusals for the FluidGrids SDK.
|
|
5
|
+
*
|
|
6
|
+
* wspace-workflow-svc meters two quotas with `@usage`, and the gateway refuses
|
|
7
|
+
* a call past either one with `429 QUOTA_EXHAUSTED`:
|
|
8
|
+
*
|
|
9
|
+
* - `fluidgrids.runs.monthly` — every mutation that starts a run:
|
|
10
|
+
* `triggerWorkflow`, `runFromNode`, `replayWorkflowRun`, `retryWorkflowRuns`
|
|
11
|
+
* and `listenForWebhookTestEvent`.
|
|
12
|
+
* - `fluidgrids.workflows.count` — the mutations that create a workflow
|
|
13
|
+
* (save, duplicate, template import). Those keep their local
|
|
14
|
+
* `QuotaExhaustedDialog`.
|
|
15
|
+
* - `fluidgrids.nodes.count` — node additions are counted by workflow save;
|
|
16
|
+
* the same save dialog handles its refusal.
|
|
17
|
+
*
|
|
18
|
+
* A run refusal opens the shell's shared upgrade prompt — see
|
|
19
|
+
* `openRunQuotaUpgradePrompt` in `./upgradePrompt`. This module is the pure
|
|
20
|
+
* detection half, so it imports nothing from `@burdenoff/fe-libs`.
|
|
21
|
+
*
|
|
22
|
+
* ★★ Why this does not just call fe-libs `isQuotaExhaustedError`. That helper
|
|
23
|
+
* reads the Apollo 3 shapes (`graphQLErrors`, `networkError.result.errors`, a
|
|
24
|
+
* code in the message). Under Apollo 4 — what every host runs — the refusal
|
|
25
|
+
* never takes those shapes:
|
|
26
|
+
*
|
|
27
|
+
* - the gateway answers `429`, and Apollo 4's HTTP link turns any non-2xx
|
|
28
|
+
* `application/json` response into a `ServerError` whose GraphQL body is
|
|
29
|
+
* only in `bodyText` (message: "Response not successful: Received status
|
|
30
|
+
* code 429");
|
|
31
|
+
* - a 2xx GraphQL error arrives as `CombinedGraphQLErrors`, whose list is
|
|
32
|
+
* `.errors`, not `.graphQLErrors`;
|
|
33
|
+
* - `throwIfResultError` wraps either one in a plain `Error`, keeping the
|
|
34
|
+
* original as `cause`.
|
|
35
|
+
*
|
|
36
|
+
* None of those match, so the refusal read as an ordinary failure. This walker
|
|
37
|
+
* reads all of them, and the Apollo 3 shapes too.
|
|
38
|
+
*/
|
|
39
|
+
/** The monthly run allowance every run-starting mutation is metered against. */
|
|
40
|
+
const RUNS_QUOTA_NAME = "fluidgrids.runs.monthly";
|
|
41
|
+
/** The workflow-count allowance save / duplicate / template import consume. */
|
|
42
|
+
const WORKFLOWS_QUOTA_NAME = "fluidgrids.workflows.count";
|
|
43
|
+
/**
|
|
44
|
+
* Where an upgrade CTA sends the user: the plan picker, not the billing
|
|
45
|
+
* overview. Matches the shared `UpgradePromptModal` default and the shell nav.
|
|
46
|
+
*/
|
|
47
|
+
const BILLING_PLANS_PATH = "/billing/plans";
|
|
48
|
+
const QUOTA_EXHAUSTED_CODE = "QUOTA_EXHAUSTED";
|
|
49
|
+
const QUOTA_NOT_PROVISIONED_CODE = "QUOTA_NOT_PROVISIONED";
|
|
50
|
+
function asRecord$1(value) {
|
|
51
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
52
|
+
}
|
|
53
|
+
/** The `extensions` of each entry of an `errors`-like list. */
|
|
54
|
+
function extensionsOfList(list) {
|
|
55
|
+
if (!Array.isArray(list)) return [];
|
|
56
|
+
const found = [];
|
|
57
|
+
for (const entry of list) {
|
|
58
|
+
const extensions = asRecord$1(asRecord$1(entry)?.extensions);
|
|
59
|
+
if (extensions) found.push(extensions);
|
|
60
|
+
}
|
|
61
|
+
return found;
|
|
62
|
+
}
|
|
63
|
+
/** The GraphQL `errors[].extensions` inside a raw response body, if it is JSON. */
|
|
64
|
+
function extensionsOfBody(bodyText) {
|
|
65
|
+
if (typeof bodyText !== "string" || !bodyText.includes("errors")) return [];
|
|
66
|
+
try {
|
|
67
|
+
return extensionsOfList(asRecord$1(JSON.parse(bodyText))?.errors);
|
|
68
|
+
} catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Bounds the `cause` walk; real chains are one or two links long. */
|
|
73
|
+
const MAX_CAUSE_DEPTH = 5;
|
|
74
|
+
/**
|
|
75
|
+
* Every `extensions` object reachable on a thrown value, across the Apollo 3
|
|
76
|
+
* and Apollo 4 shapes and the `cause` chain `throwIfResultError` adds.
|
|
77
|
+
*/
|
|
78
|
+
function collectExtensions(error) {
|
|
79
|
+
const found = [];
|
|
80
|
+
const seen = /* @__PURE__ */ new Set();
|
|
81
|
+
let current = error;
|
|
82
|
+
for (let depth = 0; depth < MAX_CAUSE_DEPTH; depth += 1) {
|
|
83
|
+
const host = asRecord$1(current);
|
|
84
|
+
if (!host || seen.has(host)) break;
|
|
85
|
+
seen.add(host);
|
|
86
|
+
const direct = asRecord$1(host.extensions);
|
|
87
|
+
if (direct) found.push(direct);
|
|
88
|
+
found.push(...extensionsOfList(host.errors));
|
|
89
|
+
found.push(...extensionsOfList(host.graphQLErrors));
|
|
90
|
+
const networkError = asRecord$1(host.networkError);
|
|
91
|
+
found.push(...extensionsOfList(asRecord$1(networkError?.result)?.errors));
|
|
92
|
+
found.push(...extensionsOfBody(networkError?.bodyText));
|
|
93
|
+
found.push(...extensionsOfList(asRecord$1(host.result)?.errors));
|
|
94
|
+
found.push(...extensionsOfBody(host.bodyText));
|
|
95
|
+
current = host.cause;
|
|
96
|
+
}
|
|
97
|
+
return found;
|
|
98
|
+
}
|
|
99
|
+
/** Every GraphQL `extensions.code` carried by `error` or its causes. */
|
|
100
|
+
function errorCodesOf(error) {
|
|
101
|
+
return collectExtensions(error).map((ext) => ext.code).filter((code) => typeof code === "string");
|
|
102
|
+
}
|
|
103
|
+
function stringField(extensions, key) {
|
|
104
|
+
const value = extensions[key];
|
|
105
|
+
return typeof value === "string" && value.length > 0 ? value : null;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* The refusal kind one GraphQL `extensions` object reports, or null.
|
|
109
|
+
*
|
|
110
|
+
* The gateway sets both `code` and `quotaBlock` on a quota refusal
|
|
111
|
+
* (`sendQuotaExhausted` in wspace-public-gateway); either is enough here, so
|
|
112
|
+
* a refusal relayed with only one of them (a proxy, an older gateway build)
|
|
113
|
+
* still reads as one.
|
|
114
|
+
*/
|
|
115
|
+
function refusalKindOf(extensions) {
|
|
116
|
+
if (extensions.code === "QUOTA_NOT_PROVISIONED" || extensions.quotaBlock === "not-provisioned") return "not-provisioned";
|
|
117
|
+
if (extensions.code === "QUOTA_EXHAUSTED" || extensions.quotaBlock === "exhausted") return "exhausted";
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* The quota refusal carried by `error`, or null when it is not one.
|
|
122
|
+
*
|
|
123
|
+
* Keyed on `extensions.code` (or the gateway's `extensions.quotaBlock`), never
|
|
124
|
+
* on the HTTP status or the message: both refusals are 429s, and only those
|
|
125
|
+
* fields tell "used up" from "never granted". `not-provisioned` wins when both
|
|
126
|
+
* appear.
|
|
127
|
+
*/
|
|
128
|
+
function findQuotaRefusal(error) {
|
|
129
|
+
const all = collectExtensions(error);
|
|
130
|
+
const notProvisioned = all.find((ext) => refusalKindOf(ext) === "not-provisioned");
|
|
131
|
+
if (notProvisioned) return {
|
|
132
|
+
kind: "not-provisioned",
|
|
133
|
+
quotaName: stringField(notProvisioned, "quotaName"),
|
|
134
|
+
limitLeft: null
|
|
135
|
+
};
|
|
136
|
+
const exhausted = all.find((ext) => refusalKindOf(ext) === "exhausted");
|
|
137
|
+
if (exhausted) {
|
|
138
|
+
const limitLeft = exhausted.limitLeft;
|
|
139
|
+
return {
|
|
140
|
+
kind: "exhausted",
|
|
141
|
+
quotaName: stringField(exhausted, "quotaName"),
|
|
142
|
+
limitLeft: typeof limitLeft === "number" ? limitLeft : null
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
/** True when `error` is an exhausted (not merely unprovisioned) plan quota. */
|
|
148
|
+
function isQuotaExhaustedFailure(error) {
|
|
149
|
+
return findQuotaRefusal(error)?.kind === "exhausted";
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// src/analytics/fluidgridsEvents.ts
|
|
153
|
+
/** `component` stamped on every event so devtools/OTel can tell the emitter. */
|
|
154
|
+
const FLUIDGRIDS_ANALYTICS_COMPONENT = "fluidgrids-fe-sdk";
|
|
155
|
+
/** Upper bound for a slug-like dimension; anything longer is not a slug. */
|
|
156
|
+
const MAX_DIMENSION_LENGTH = 64;
|
|
157
|
+
const SLUG_PATTERN = /^[A-Za-z0-9][A-Za-z0-9_./:-]*$/;
|
|
158
|
+
/**
|
|
159
|
+
* Keep a dimension only when it is a short slug (`integration/slack`,
|
|
160
|
+
* `trigger_webhook`, `marketing`). Anything else — spaces, free text, a very
|
|
161
|
+
* long value — is dropped rather than risk sending user data.
|
|
162
|
+
*/
|
|
163
|
+
function toDimension(value) {
|
|
164
|
+
if (typeof value !== "string") return void 0;
|
|
165
|
+
const trimmed = value.trim();
|
|
166
|
+
if (!trimmed || trimmed.length > MAX_DIMENSION_LENGTH) return void 0;
|
|
167
|
+
return SLUG_PATTERN.test(trimmed) ? trimmed : void 0;
|
|
168
|
+
}
|
|
169
|
+
/** Non-empty string id, or undefined. */
|
|
170
|
+
function idOrUndefined(value) {
|
|
171
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
172
|
+
}
|
|
173
|
+
/** A finite, non-negative integer count, or undefined. */
|
|
174
|
+
function countOrUndefined(value) {
|
|
175
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? Math.round(value) : void 0;
|
|
176
|
+
}
|
|
177
|
+
function emit(bus, name, payload) {
|
|
178
|
+
if (!bus) return;
|
|
179
|
+
const clean = Object.fromEntries(Object.entries(payload).filter(([, value]) => value !== void 0));
|
|
180
|
+
try {
|
|
181
|
+
bus.emit(name, clean, { component: FLUIDGRIDS_ANALYTICS_COMPONENT });
|
|
182
|
+
} catch (error) {
|
|
183
|
+
console.warn(`[fluidgrids analytics] failed to emit ${name}`, error);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function asRecord(value) {
|
|
187
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : null;
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* The executable node list of a workflow definition, wherever it sits: the
|
|
191
|
+
* flow store's `{ nodes }`, a saved `definitionJson` (`{ data: { nodes } }`) or
|
|
192
|
+
* a raw list.
|
|
193
|
+
*/
|
|
194
|
+
function nodesOf(definition) {
|
|
195
|
+
if (Array.isArray(definition)) return definition;
|
|
196
|
+
const record = asRecord(definition);
|
|
197
|
+
if (!record) return [];
|
|
198
|
+
if (Array.isArray(record.nodes)) return record.nodes;
|
|
199
|
+
const data = asRecord(record.data);
|
|
200
|
+
if (data && Array.isArray(data.nodes)) return data.nodes;
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
function isTriggerNode(node) {
|
|
204
|
+
if ((typeof node.type === "string" ? node.type.toLowerCase() : "").includes("trigger")) return true;
|
|
205
|
+
const data = asRecord(node.data);
|
|
206
|
+
return data?.isTrigger === true || data?.category === "trigger";
|
|
207
|
+
}
|
|
208
|
+
/** Node-type slug of the workflow's trigger node, when it has one. */
|
|
209
|
+
function triggerTypeOf(definition) {
|
|
210
|
+
const trigger = nodesOf(definition).find(isTriggerNode);
|
|
211
|
+
return trigger ? toDimension(trigger.type) : void 0;
|
|
212
|
+
}
|
|
213
|
+
/** Number of executable nodes on the canvas. */
|
|
214
|
+
function nodeCountOf(definition) {
|
|
215
|
+
const nodes = nodesOf(definition);
|
|
216
|
+
return nodes.length > 0 ? nodes.length : void 0;
|
|
217
|
+
}
|
|
218
|
+
/** `fluidgrids.workflow.created` — a new workflow exists in the workspace. */
|
|
219
|
+
function emitWorkflowCreated(bus, fact) {
|
|
220
|
+
emit(bus, "fluidgrids.workflow.created", {
|
|
221
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
222
|
+
workflowId: idOrUndefined(fact.workflowId),
|
|
223
|
+
source: fact.source,
|
|
224
|
+
triggerType: triggerTypeOf(fact.definition),
|
|
225
|
+
nodeCount: nodeCountOf(fact.definition)
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
/** `fluidgrids.workflow.published` — a version was activated. */
|
|
229
|
+
function emitWorkflowPublished(bus, fact) {
|
|
230
|
+
emit(bus, "fluidgrids.workflow.published", {
|
|
231
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
232
|
+
workflowId: idOrUndefined(fact.workflowId),
|
|
233
|
+
triggerType: triggerTypeOf(fact.definition),
|
|
234
|
+
nodeCount: nodeCountOf(fact.definition)
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
/** `fluidgrids.workflow.run_started` — the backend accepted a run. */
|
|
238
|
+
function emitRunStarted(bus, fact) {
|
|
239
|
+
emit(bus, "fluidgrids.workflow.run_started", {
|
|
240
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
241
|
+
workflowId: idOrUndefined(fact.workflowId),
|
|
242
|
+
executionId: idOrUndefined(fact.executionId),
|
|
243
|
+
trigger: fact.trigger
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* `fluidgrids.workflow.run_failed` — a run this user started ended FAILED.
|
|
248
|
+
* `errorCode` is the run's machine error classification (`TIMEOUT`,
|
|
249
|
+
* `VALIDATION`, …), never its message.
|
|
250
|
+
*/
|
|
251
|
+
function emitRunFailed(bus, fact) {
|
|
252
|
+
emit(bus, "fluidgrids.workflow.run_failed", {
|
|
253
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
254
|
+
workflowId: idOrUndefined(fact.workflowId),
|
|
255
|
+
executionId: idOrUndefined(fact.executionId),
|
|
256
|
+
trigger: fact.trigger,
|
|
257
|
+
errorCode: toDimension(fact.errorCode),
|
|
258
|
+
durationMs: countOrUndefined(fact.durationMs)
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
/** `fluidgrids.template.used` — a store template became a workflow. */
|
|
262
|
+
function emitTemplateUsed(bus, fact) {
|
|
263
|
+
emit(bus, "fluidgrids.template.used", {
|
|
264
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
265
|
+
templateId: idOrUndefined(fact.templateId),
|
|
266
|
+
category: toDimension(fact.category)
|
|
267
|
+
});
|
|
268
|
+
}
|
|
269
|
+
/** `fluidgrids.node.installed` — a store node was installed. */
|
|
270
|
+
function emitNodeInstalled(bus, fact) {
|
|
271
|
+
emit(bus, "fluidgrids.node.installed", {
|
|
272
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
273
|
+
nodeType: toDimension(fact.nodeType),
|
|
274
|
+
source: fact.source
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
/** `fluidgrids.quota.workflow_limit_hit` — a create was refused at the limit. */
|
|
278
|
+
function emitWorkflowLimitHit(bus, fact) {
|
|
279
|
+
emit(bus, "fluidgrids.quota.workflow_limit_hit", {
|
|
280
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
281
|
+
quotaKey: WORKFLOWS_QUOTA_NAME,
|
|
282
|
+
surface: fact.surface
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
/** `fluidgrids.quota.run_limit_hit` — a run was refused at the monthly limit. */
|
|
286
|
+
function emitRunLimitHit(bus, fact) {
|
|
287
|
+
emit(bus, "fluidgrids.quota.run_limit_hit", {
|
|
288
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
289
|
+
quotaKey: toDimension(fact.quotaKey) ?? "fluidgrids.runs.monthly",
|
|
290
|
+
surface: fact.surface
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
/** `fluidgrids.billing.upgrade_clicked` — a FluidGrids upgrade CTA was clicked. */
|
|
294
|
+
function emitUpgradeClicked(bus, fact) {
|
|
295
|
+
emit(bus, "fluidgrids.billing.upgrade_clicked", {
|
|
296
|
+
workspaceId: idOrUndefined(fact.workspaceId),
|
|
297
|
+
surface: fact.surface,
|
|
298
|
+
quotaKey: toDimension(fact.quotaKey)
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Map a run's backend mode/trigger to the analytics trigger dimension. The
|
|
303
|
+
* builder's debug paths are always `TEST`; anything else a person started by
|
|
304
|
+
* hand is `manual`.
|
|
305
|
+
*/
|
|
306
|
+
function runTriggerFromMode(mode) {
|
|
307
|
+
return typeof mode === "string" && mode.toUpperCase() === "TEST" ? "test" : "manual";
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
export { errorCodesOf as _, emitTemplateUsed as a, emitWorkflowLimitHit as c, runTriggerFromMode as d, BILLING_PLANS_PATH as f, collectExtensions as g, WORKFLOWS_QUOTA_NAME as h, emitRunStarted as i, emitWorkflowPublished as l, RUNS_QUOTA_NAME as m, emitRunFailed as n, emitUpgradeClicked as o, QUOTA_EXHAUSTED_CODE as p, emitRunLimitHit as r, emitWorkflowCreated as s, emitNodeInstalled as t, nodesOf as u, findQuotaRefusal as v, isQuotaExhaustedFailure as y };
|
package/dist/history.js
CHANGED