@burdenoff/fluidgrids-fe-sdk 2026.1113.1 → 2026.1113.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AiStudioPage-D3MAk-bs.js → AiStudioPage-5KYZ8r8-.js} +464 -7
- package/dist/{ApprovalInboxPage-Bb8H9ruw.js → ApprovalInboxPage-BsJX4osU.js} +4 -3
- package/dist/{ConnectionFormDialog-Bg9_OdHX.js → ConnectionFormDialog-Dr1-CTan.js} +2 -1
- package/dist/CreateFluidgridsTagDocument-Dtp9KPLJ.js +1055 -0
- package/dist/{DataSinkDashboardPage-Dc2QuJbL.js → DataSinkDashboardPage-8ZDn85e2.js} +1 -1
- package/dist/{DataTablesPage-Cv4veaKK.js → DataTablesPage-BBvABuxE.js} +5 -4
- package/dist/{EntityTagPicker-D8ws706D.js → EntityTagPicker-BppBSEJk.js} +2 -2
- package/dist/{ExecutionDetailPage-CTVGE-d-.js → ExecutionDetailPage-BXDF2eoT.js} +1444 -18
- package/dist/ExecutionsListDocument-CzdLPpj5.js +1259 -0
- package/dist/{ExecutionsListPage-J0sJPuoM.js → ExecutionsListPage--4BthM8L.js} +285 -11
- package/dist/FailureTriagePanel-B5WCSRFo.js +1252 -0
- package/dist/{FluidGridsProvider-C4FVNz0n.js → FluidGridsProvider-Dc_Jhtch.js} +8666 -8734
- package/dist/{HistoryPage-B9XcTPrO.js → HistoryPage-BvFk2m1m.js} +4 -3
- package/dist/{InsightsPage-DFOltjyj.js → InsightsPage-Dwmb02F6.js} +2682 -5
- package/dist/{MissingNodesInstallModal-D8H-YNCJ.js → MissingNodesInstallModal-Cze674hp.js} +2 -2
- package/dist/{NodesPage-YQ-hP60x.js → NodesPage-C5Dq-ru-.js} +3 -2
- package/dist/{OpenTemplateAsCodeButton-hH26HQCk.js → OpenTemplateAsCodeButton-8MZHih6I.js} +2 -2
- package/dist/{PaidTemplateConfirm-DoKWMBtR.js → PaidTemplateConfirm-0G-gv29n.js} +1 -1
- package/dist/{PublishCustomNodeAction-5XXnSA3H.js → PublishCustomNodeAction-OOY35dUv.js} +1 -1
- package/dist/QuotaExhaustedDialog-wvu_-WJ-.js +55 -0
- package/dist/{RunnerStatusPill-Ctg4TJcP.js → RunnerStatusPill-Bh7mEsPh.js} +2 -1
- package/dist/{RunnersPage-CAt4YDhB.js → RunnersPage-DHeuUDil.js} +2 -2
- package/dist/{SettingsPage-DEKPCVVP.js → SettingsPage-CfjXiGpb.js} +694 -14
- package/dist/{TagFilterSelect-CwM2-DU6.js → TagFilterSelect-CAShgvbS.js} +1 -1
- package/dist/{TaskQueuesPage-Dhi6SIT4.js → TaskQueuesPage--Mmn36b-.js} +3 -3
- package/dist/{TemplateCard-DVSd_4zJ.js → TemplateCard-BA_9em22.js} +644 -352
- package/dist/{TemplateConfigurationModal-BKi1z7z7.js → TemplateConfigurationModal-BT3PaR0O.js} +4 -3
- package/dist/{TemplateDetailPanel-DK1gF7P5.js → TemplateDetailPanel-BxFNnlXm.js} +2 -1
- package/dist/{TemplatePreview-DuSX2Q7H.js → TemplatePreview-Bagja6WN.js} +7 -7
- package/dist/{TemplatesPage-CAWHh61l.js → TemplatesPage-CAajpJ5w.js} +711 -6
- package/dist/{VariablesPage-D7CoatWf.js → VariablesPage-CgUBKhAe.js} +3 -3
- package/dist/{VersionDiffDialog-DGwysiyE.js → VersionDiffDialog-D9W5Fm56.js} +233 -129
- package/dist/VersionLifecycleBar-DuphLOT0.js +131 -0
- package/dist/{WorkflowBuilder-DAeoQi5E.js → WorkflowBuilder-DMpSPElu.js} +16 -13
- package/dist/{WorkflowBuilder-BJgqDboZ.js → WorkflowBuilder-v8h8skwG.js} +5 -5
- package/dist/WorkflowDefinitionDocument-DZLbTPUZ.js +321 -0
- package/dist/WorkflowEditLeaseStatusDocument-Dp62med3.js +627 -0
- package/dist/WorkflowProposalCard-zCdUpCk8.js +249 -0
- package/dist/WorkflowProposalDocument-BdUbsrd0.js +620 -0
- package/dist/{WorkflowSearchRedirect-CMEvd_AR.js → WorkflowSearchRedirect-G78lINAE.js} +1 -1
- package/dist/{WorkflowShareDialog-BgHRsDP0.js → WorkflowShareDialog-B7VOgr4-.js} +304 -3
- package/dist/WorkflowVersionsDocument-CfPMloRW.js +3195 -0
- package/dist/{WorkflowsList-CcQPxWKL.js → WorkflowsList-CPYzfE4K.js} +11 -9
- package/dist/agent-form-D0uLvzx4.js +718 -0
- package/dist/{agentTools-DKpNKztf.js → agentTools-DTXUqtfu.js} +4 -4
- package/dist/api-BZVyX5d2.js +2286 -0
- package/dist/api-BqA-f-AD.js +8064 -0
- package/dist/app-BJUvugPM.js +3813 -0
- package/dist/assert-rules-CPNrO44K.js +318 -0
- package/dist/attach-node-helpers-CNsYtLOR.js +32 -0
- package/dist/badge-CXfPhoMH.js +26 -0
- package/dist/{canvasNoteTools-C_AN79m0.js → canvasNoteTools-DmfZwtnL.js} +3 -3
- package/dist/{channel-CZ70oI81.js → channel-DtF1n_ab.js} +1 -1
- package/dist/client-Ctl4jmY3.js +127 -0
- package/dist/code-editor-diagnostics-Zr0cIcx1.js +46 -0
- package/dist/{code-editor-field-Dt6KNWwN.js → code-editor-field-Cv907s3W.js} +2 -2
- package/dist/{codec-client-CJ95Rmqo.js → codec-client-CAYl6j46.js} +2 -1
- package/dist/conditionBuilder-D8aLGL1w.js +1134 -0
- package/dist/config-X97zrIvn.js +600 -0
- package/dist/{definition-canvas-Bshn_dSP.js → definition-canvas-DL25_6NH.js} +1 -1
- package/dist/{dialog-Cjb4lB4D.js → dialog-BVd152GS.js} +3 -14
- package/dist/durable-nodes-DXCCQYWD.js +81 -0
- package/dist/errors-xPZ-IbQd.js +142 -0
- package/dist/executions.js +2 -2
- package/dist/{flow-builder-D3Hl2AFk.js → flow-builder-Dv5fWJ6F.js} +9301 -8189
- package/dist/{node-registry-refresh-Dy0uRg9f.js → global-client-DP_Wxe5t.js} +2 -27
- package/dist/global-operations-7pvXw_j9.js +145 -0
- package/dist/history.js +1 -1
- package/dist/{index-CWcP-tG1.d.ts → index-DtMUtXNq.d.ts} +247 -247
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4403 -46
- package/dist/input-ChT6Q-Pr.js +17 -0
- package/dist/logs-panel-DtG93ocy.js +342 -0
- package/dist/mapping-colors-BIX_YeCQ.js +48 -0
- package/dist/{node-detail-view-bVLeYarT.js → node-detail-view-BKI_2kM6.js} +12 -11
- package/dist/{node-editor-tab-body-JHHVtQgR.js → node-editor-tab-body-Cc1MWEFR.js} +3 -3
- package/dist/{node-operation-selection-DAbS6jSY.js → node-operation-selection-Czeeb2D4.js} +2 -139
- package/dist/node-registry-refresh-s3okf83X.js +27 -0
- package/dist/nodes.js +1 -1
- package/dist/notesKey-5EaREBGA.js +12 -0
- package/dist/observability.d.ts +1 -1
- package/dist/observability.js +2 -2
- package/dist/{popover-Xx3gN7vg.js → popover-DDv7J1Kl.js} +717 -6
- package/dist/{quick-config-panel-BvVQXuIL.js → quick-config-panel-BPCRfqWI.js} +4 -4
- package/dist/read-only-context-Dt9N9SIG.js +18 -0
- package/dist/{schedule-panel-DCb40TPN.js → schedule-panel-C1KwfLCE.js} +14 -12
- package/dist/settings.js +1 -1
- package/dist/{shared-CMfn30xT.js → shared-Ctl9ZHo1.js} +2 -1
- package/dist/{sidebar-node-editor-DxCWFZG2.js → sidebar-node-editor-d9Rlq5pU.js} +4 -4
- package/dist/sticky-notes-23j-wL6Q.js +96 -0
- package/dist/template-code-dqRunGOv.js +184 -0
- package/dist/template-preview-C01KV277.js +29 -0
- package/dist/templates.js +2 -2
- package/dist/token-refresh-link-BjN7H4qA.js +291 -0
- package/dist/useAgentDefinitions-ZKX2N9aP.js +3101 -0
- package/dist/useConnections-BlB0gbOB.js +931 -0
- package/dist/useDurableParity-BgLH_SCF.js +2088 -0
- package/dist/{useEntityTags-Db4Pc8_M.js → useEntityTags-4iW6UTly.js} +227 -3
- package/dist/{useExecutions-DOpG1pUQ.js → useExecutions-Bm7q_UwN.js} +6 -3
- package/dist/useGlobalStoreClient-DMTrywdX.js +24 -0
- package/dist/{useHumanRequests-ZiR0sSzS.js → useHumanRequests-DwG2tQ3f.js} +2 -1
- package/dist/{useObservability-rQmwhoZZ.js → useObservability-DPATdbw7.js} +4 -2
- package/dist/{useRunHistory-COn6dl7l.js → useRunHistory-CGfjCsJ3.js} +1122 -4
- package/dist/{useVariables-2ddyJX4a.js → useVariables-DFdZofLQ.js} +2 -1
- package/dist/{useWorkflowCodeExport-ZoUJKRSK.js → useWorkflowCodeExport-D_mCuhKP.js} +289 -4
- package/dist/useWorkflowOrganization-r5FWNBs6.js +1690 -0
- package/dist/useWorkflowProposal-Bh2_qjmM.js +7478 -0
- package/dist/{useWorkflows-jOW60YmD.js → useWorkflows-aqVD7kGa.js} +694 -4
- package/dist/workflow-builder.js +5 -5
- package/dist/{workflow-code-transfer-l9wO34S0.js → workflow-code-transfer-5C0HUzae.js} +1 -53
- package/dist/workflow-host.js +4 -2
- package/dist/workflow-pages.d.ts +1 -1
- package/dist/workflow-pages.js +19 -19
- package/dist/workflow-preview.js +3 -2
- package/dist/workflows-list.js +1 -1
- package/package.json +1 -1
- package/dist/FailureTriagePanel-BbYFYeV_.js +0 -311
- package/dist/WorkflowProposalCard-DGMdZC4R.js +0 -1432
- package/dist/agent-form-Bfvm32j1.js +0 -83
- package/dist/api-DQtHXbIg.js +0 -224
- package/dist/api-MeAm6g7E.js +0 -55
- package/dist/client-C9XSzSXr.js +0 -1147
- package/dist/graphql-operation-types-C9qbvRa8.js +0 -53122
- package/dist/useAgentDefinitions-_hgNCK1A.js +0 -550
- package/dist/useConnections-Cs7LCWEM.js +0 -401
- package/dist/useDurableParity-CcLeCDfv.js +0 -504
- package/dist/useWorkflowOrganization-QxVePSkk.js +0 -282
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { A as
|
|
3
|
-
import {
|
|
4
|
-
import { i as NodeInputFields, n as useNodeEditorTab, r as NodeEditorTabs, t as NodeEditorTabBody } from "./node-editor-tab-body-
|
|
2
|
+
import { A as NodeTypeIcon, M as useFlowStore, k as nodeAccent } from "./node-operation-selection-Czeeb2D4.js";
|
|
3
|
+
import { F as nodeTitle, In as getNodeDetail, Jt as useNodeExecution, P as nodeSubtitle, z as useNodeConfig } from "./FluidGridsProvider-Dc_Jhtch.js";
|
|
4
|
+
import { i as NodeInputFields, n as useNodeEditorTab, r as NodeEditorTabs, t as NodeEditorTabBody } from "./node-editor-tab-body-Cc1MWEFR.js";
|
|
5
5
|
import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
|
|
6
|
-
import { r as NodeExecutionActions } from "./schedule-panel-
|
|
6
|
+
import { r as NodeExecutionActions } from "./schedule-panel-C1KwfLCE.js";
|
|
7
7
|
import { useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
|
|
8
8
|
import { useReactFlow, useStore } from "@xyflow/react";
|
|
9
9
|
import { Icon } from "@iconify/react";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
|
|
4
|
+
// src/builder/components/flow-builder/read-only-context.ts
|
|
5
|
+
/**
|
|
6
|
+
* Whether the builder is read-only: the `readOnly` prop or `?readonly=true`
|
|
7
|
+
* (embeds, template previews), or someone else holding the workflow's edit
|
|
8
|
+
* lease (BOFF-9725). Provided by `FlowBuilder` for the whole canvas, so node
|
|
9
|
+
* cards, sticky notes and the node panels stop changing the workflow and
|
|
10
|
+
* controls with side effects can hide themselves.
|
|
11
|
+
*/
|
|
12
|
+
const BuilderReadOnlyContext = createContext(false);
|
|
13
|
+
const BuilderReadOnlyProvider = BuilderReadOnlyContext.Provider;
|
|
14
|
+
function useBuilderReadOnly() {
|
|
15
|
+
return useContext(BuilderReadOnlyContext);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export { useBuilderReadOnly as n, BuilderReadOnlyProvider as t };
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { r as getFluidGridsConfig } from "./config-X97zrIvn.js";
|
|
3
|
+
import { o as throwIfResultError, t as describeOperationError } from "./errors-xPZ-IbQd.js";
|
|
4
|
+
import { n as getFluidGridsClient, r as getFluidGridsClientSafe } from "./client-Ctl4jmY3.js";
|
|
5
|
+
import { M as useFlowStore } from "./node-operation-selection-Czeeb2D4.js";
|
|
6
|
+
import { $ as missingRequiredParameters, $t as parseParameterValue, F as nodeTitle, G as resolveLoadOptionsSpec, H as isStringOptionList, I as optionText, J as casesFromRules, K as ConditionTreeBuilder, L as paramsFromOperation, M as coerceNumber, Q as boundFieldsOf, Qt as formatParameterValue, U as optionListText, W as optionListValues, X as parseMappingValue, an as openRunQuotaUpgradePrompt, en as structuredParameterType, in as useFluidGridsAnalytics, j as asRecord, k as useRunGuard, q as SwitchRulesEditor, rn as isParamVisible, t as FluidGridsContext, yt as useSaveStatusStore } from "./FluidGridsProvider-Dc_Jhtch.js";
|
|
7
|
+
import { n as useBuilderReadOnly } from "./read-only-context-Dt9N9SIG.js";
|
|
5
8
|
import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
+
import { L as triggerSchedule, T as pauseSchedule, t as backfillSchedule, u as describeSchedule, z as unpauseSchedule } from "./api-BqA-f-AD.js";
|
|
10
|
+
import { on as PreviewScheduleDocument, t as useAgentDefinitionList, vt as useRunFromNodeEligibilityQuery } from "./useAgentDefinitions-ZKX2N9aP.js";
|
|
11
|
+
import { r as describeRule, s as isAgentNodeType } from "./agent-form-D0uLvzx4.js";
|
|
12
|
+
import { a as ConnectionSelector, c as StopWebhookTestListenerDocument, i as RunOnSection, l as ListenForWebhookTestEventDocument, n as PopoverContent$1, o as WorkflowCallInputsDocument, r as PopoverTrigger$1, s as WebhookTestListenerDocument, t as Popover$1, u as ListenForFormTestSubmissionDocument } from "./popover-DDv7J1Kl.js";
|
|
9
13
|
import { a as collectExtensions } from "./quota-Cdt8yz7N.js";
|
|
10
14
|
import { pO as ScheduleType, xI as WorkflowScheduleOverlapPolicy } from "./graphql-types-v6CTGwA0.js";
|
|
11
|
-
import {
|
|
12
|
-
import { r as
|
|
13
|
-
import { i as NativeSelect, o as StatusPill, t as FieldError, u as useResource } from "./shared-
|
|
14
|
-
import {
|
|
15
|
-
import { a as ConnectionSelector, i as RunOnSection, n as PopoverContent$1, r as PopoverTrigger$1, t as Popover$1 } from "./popover-Xx3gN7vg.js";
|
|
16
|
-
import { r as normalizeCodeLanguage, t as CodeEditorField } from "./code-editor-field-Dt6KNWwN.js";
|
|
15
|
+
import { t as useGlobalStoreClient } from "./useGlobalStoreClient-DMTrywdX.js";
|
|
16
|
+
import { a as operatorSpec, c as ruleFromRow, i as normaliseAssertRules, n as describeAssertRuleProblem, o as readAssertRulesSetting, r as emptyAssertRuleRow, s as rowsFromRules, t as ASSERT_OPERATORS } from "./assert-rules-CPNrO44K.js";
|
|
17
|
+
import { i as NativeSelect, o as StatusPill, t as FieldError, u as useResource } from "./shared-Ctl9ZHo1.js";
|
|
18
|
+
import { r as normalizeCodeLanguage, t as CodeEditorField } from "./code-editor-field-Cv907s3W.js";
|
|
17
19
|
import { useCallback, useContext, useEffect, useId, useMemo, useRef, useState } from "react";
|
|
18
20
|
import { Icon } from "@iconify/react";
|
|
19
21
|
import { cn } from "@burdenoff/fe-libs/utils";
|
package/dist/settings.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as SettingsPage } from "./SettingsPage-
|
|
2
|
+
import { t as SettingsPage } from "./SettingsPage-CfjXiGpb.js";
|
|
3
3
|
import { t as ManagedAiPolicyAuthorityProvider } from "./ManagedAiPolicyAuthority-BxwJ3ptd.js";
|
|
4
4
|
|
|
5
5
|
export { ManagedAiPolicyAuthorityProvider, SettingsPage };
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import {
|
|
2
|
+
import { o as throwIfResultError, t as describeOperationError } from "./errors-xPZ-IbQd.js";
|
|
3
|
+
import { n as getFluidGridsClient } from "./client-Ctl4jmY3.js";
|
|
3
4
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
5
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
6
|
import { Label, Textarea } from "@burdenoff/fe-libs/ui";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { A as
|
|
3
|
-
import {
|
|
4
|
-
import { i as NodeInputFields, n as useNodeEditorTab, r as NodeEditorTabs, t as NodeEditorTabBody } from "./node-editor-tab-body-
|
|
5
|
-
import { r as NodeExecutionActions } from "./schedule-panel-
|
|
2
|
+
import { A as NodeTypeIcon, M as useFlowStore, k as nodeAccent } from "./node-operation-selection-Czeeb2D4.js";
|
|
3
|
+
import { F as nodeTitle, In as getNodeDetail, Jt as useNodeExecution, P as nodeSubtitle, z as useNodeConfig } from "./FluidGridsProvider-Dc_Jhtch.js";
|
|
4
|
+
import { i as NodeInputFields, n as useNodeEditorTab, r as NodeEditorTabs, t as NodeEditorTabBody } from "./node-editor-tab-body-Cc1MWEFR.js";
|
|
5
|
+
import { r as NodeExecutionActions } from "./schedule-panel-C1KwfLCE.js";
|
|
6
6
|
import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
|
|
7
7
|
import { useEffect, useState } from "react";
|
|
8
8
|
import { Icon } from "@iconify/react";
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/builder/contants/symbols.ts
|
|
3
|
+
const NODE_TYPE_DRAG_DATA_FORMAT = "application/flow-builder.node-type";
|
|
4
|
+
/**
|
|
5
|
+
* Optional companion to NODE_TYPE_DRAG_DATA_FORMAT: carries the operation name
|
|
6
|
+
* a node instance should be pinned to when dropped. Set by the Node Store
|
|
7
|
+
* operation rows so a dragged operation lands on the canvas already configured
|
|
8
|
+
* (no on-card operation dropdown). Absent for built-in / control-flow drags.
|
|
9
|
+
*/
|
|
10
|
+
const NODE_OPERATION_DRAG_DATA_FORMAT = "application/flow-builder.node-operation";
|
|
11
|
+
/**
|
|
12
|
+
* Node type of the canvas sticky note (n8n-style annotation). Stickies are
|
|
13
|
+
* pure canvas decorations persisted in the workflow definition: they have no
|
|
14
|
+
* handles, are skipped by flow validation, and are never reached by execution
|
|
15
|
+
* (the run planner is trigger-rooted and edge-driven).
|
|
16
|
+
*/
|
|
17
|
+
const STICKY_NOTE_TYPE = "sticky-note";
|
|
18
|
+
|
|
19
|
+
// src/builder/lib/sticky-notes.ts
|
|
20
|
+
/**
|
|
21
|
+
* Sticky notes are persisted OUTSIDE `definitionJson.data.nodes`, under a
|
|
22
|
+
* sibling `stickyNotes` key, so nothing execution-adjacent (backend
|
|
23
|
+
* validators, run planning, trigger sync, analytics over nodes) ever sees
|
|
24
|
+
* them. On the canvas they still live as React Flow nodes; these helpers
|
|
25
|
+
* convert between the two shapes at the save/load boundary.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* n8n-parity sticky-note palette. The keys are persisted in workflow JSON
|
|
29
|
+
* (`data.color`); each value is built from semantic categorical tokens
|
|
30
|
+
* (fe-libs chart-* series), so the tints follow light/dark mode and the brand
|
|
31
|
+
* themes. The default theme has no orange series, so orange is mixed from
|
|
32
|
+
* the yellow and red series rather than borrowed from a status token: the
|
|
33
|
+
* warning token resolves to the same hue as chart-4, which made orange and
|
|
34
|
+
* yellow notes look identical.
|
|
35
|
+
*/
|
|
36
|
+
const STICKY_COLORS = {
|
|
37
|
+
yellow: "var(--color-chart-4)",
|
|
38
|
+
orange: "color-mix(in srgb, var(--color-chart-4) 50%, var(--color-chart-5))",
|
|
39
|
+
blue: "var(--color-chart-1)",
|
|
40
|
+
green: "var(--color-chart-2)",
|
|
41
|
+
red: "var(--color-chart-5)",
|
|
42
|
+
purple: "var(--color-chart-3)",
|
|
43
|
+
gray: "var(--color-chart-axis)"
|
|
44
|
+
};
|
|
45
|
+
const DEFAULT_STICKY_COLOR = "yellow";
|
|
46
|
+
/** Palette key for a stored note colour; unknown or missing keys fall back to the default. */
|
|
47
|
+
function resolveStickyColor(color) {
|
|
48
|
+
return typeof color === "string" && Object.hasOwn(STICKY_COLORS, color) ? color : DEFAULT_STICKY_COLOR;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Opacity of a sticky note's body fill and border, in percent. These match
|
|
52
|
+
* the hex alpha suffixes the notes used before the palette moved to semantic
|
|
53
|
+
* tokens (`1F` ≈ 12 %, `59` ≈ 35 %), so existing notes look the same.
|
|
54
|
+
*/
|
|
55
|
+
const STICKY_FILL_PERCENT = 12;
|
|
56
|
+
const STICKY_BORDER_PERCENT = 35;
|
|
57
|
+
/**
|
|
58
|
+
* Translucent tint of a palette colour. The palette holds CSS variables
|
|
59
|
+
* (`var(--color-chart-4)`), so a hex alpha suffix cannot be appended: the
|
|
60
|
+
* result (`var(--color-chart-4)1F`) is invalid CSS and the browser drops the
|
|
61
|
+
* whole declaration. `color-mix` works with any colour value, including
|
|
62
|
+
* variables, and keeps the note following the active theme.
|
|
63
|
+
*/
|
|
64
|
+
function stickyTint(color, percent) {
|
|
65
|
+
return `color-mix(in srgb, ${color} ${Math.min(100, Math.max(0, percent))}%, transparent)`;
|
|
66
|
+
}
|
|
67
|
+
/** Inline fill and border colours for a sticky note body. */
|
|
68
|
+
function stickySurfaceStyle(color) {
|
|
69
|
+
return {
|
|
70
|
+
backgroundColor: stickyTint(color, 12),
|
|
71
|
+
borderColor: stickyTint(color, 35)
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
function isStickyNode(node) {
|
|
75
|
+
return node?.type === STICKY_NOTE_TYPE;
|
|
76
|
+
}
|
|
77
|
+
/** Split canvas nodes into executable nodes and sticky notes (for save). */
|
|
78
|
+
function partitionStickyNotes(nodes) {
|
|
79
|
+
return {
|
|
80
|
+
nodes: nodes.filter((n) => !isStickyNode(n)),
|
|
81
|
+
stickyNotes: nodes.filter((n) => isStickyNode(n))
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Combine a loaded definition's nodes + stickyNotes into one canvas node list
|
|
86
|
+
* (for load). Tolerates legacy definitions that still carry sticky nodes
|
|
87
|
+
* inside `nodes` (de-duplicated by id).
|
|
88
|
+
*/
|
|
89
|
+
function mergeStickyNotes(def) {
|
|
90
|
+
const nodes = Array.isArray(def.nodes) ? def.nodes : [];
|
|
91
|
+
const stickies = Array.isArray(def.stickyNotes) ? def.stickyNotes : [];
|
|
92
|
+
const seen = new Set(nodes.map((n) => n.id));
|
|
93
|
+
return [...nodes, ...stickies.filter((s) => s?.id && !seen.has(s.id))];
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { resolveStickyColor as a, NODE_TYPE_DRAG_DATA_FORMAT as c, partitionStickyNotes as i, STICKY_NOTE_TYPE as l, STICKY_COLORS as n, stickySurfaceStyle as o, mergeStickyNotes as r, NODE_OPERATION_DRAG_DATA_FORMAT as s, DEFAULT_STICKY_COLOR as t };
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { b as utf8Length } from "./workflow-code-transfer-5C0HUzae.js";
|
|
3
|
+
|
|
4
|
+
// src/utils/template-code.ts
|
|
5
|
+
/** DD3: the largest `content.sources` the store accepts, as UTF-8 JSON. */
|
|
6
|
+
const TEMPLATE_SOURCES_MAX_BYTES = 1048576;
|
|
7
|
+
/** DD3: the most files `content.sources` may hold. */
|
|
8
|
+
const TEMPLATE_SOURCES_MAX_FILES = 64;
|
|
9
|
+
/** The only package a tier-2 template's sources may import (C-TEMPLATE). */
|
|
10
|
+
const TEMPLATE_RUNTIME_PACKAGE = "@fluidgrids/workflows";
|
|
11
|
+
var TemplateCodeError = class extends Error {
|
|
12
|
+
problem;
|
|
13
|
+
constructor(problem) {
|
|
14
|
+
super(`Template code refused: ${problem.code}`);
|
|
15
|
+
this.problem = problem;
|
|
16
|
+
this.name = "TemplateCodeError";
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
function isRecord(value) {
|
|
20
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Whether a source path is a plain relative POSIX path, as global-store-svc
|
|
24
|
+
* requires: not empty, not absolute, no drive letter, no backslash, no `.`,
|
|
25
|
+
* `..` or empty segment, and no control character.
|
|
26
|
+
*/
|
|
27
|
+
function isSafeTemplateSourcePath(path) {
|
|
28
|
+
if (!path || path.startsWith("/") || path.includes("\\")) return false;
|
|
29
|
+
if (/^[A-Za-z]:/.test(path)) return false;
|
|
30
|
+
for (const character of path) {
|
|
31
|
+
const code = character.charCodeAt(0);
|
|
32
|
+
if (code < 32 || code === 127) return false;
|
|
33
|
+
}
|
|
34
|
+
return path.split("/").every((segment) => segment !== "" && segment !== "." && segment !== "..");
|
|
35
|
+
}
|
|
36
|
+
/** Bytes the store counts for a sources list: its UTF-8 JSON. */
|
|
37
|
+
function templateSourcesBytes(sources) {
|
|
38
|
+
return utf8Length(JSON.stringify(sources));
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Module specifiers a source imports: static and dynamic `import`, `export
|
|
42
|
+
* … from` and `require`. Comments are not stripped, so a commented-out import
|
|
43
|
+
* is counted too; that only makes the check stricter.
|
|
44
|
+
*/
|
|
45
|
+
function importedSpecifiers(source) {
|
|
46
|
+
const found = [];
|
|
47
|
+
for (const pattern of [
|
|
48
|
+
/\b(?:import|export)\s[^'"`;]*?\bfrom\s*['"]([^'"]+)['"]/g,
|
|
49
|
+
/\bimport\s*['"]([^'"]+)['"]/g,
|
|
50
|
+
/\bimport\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
|
|
51
|
+
/\brequire\s*\(\s*['"]([^'"]+)['"]\s*\)/g
|
|
52
|
+
]) for (const match of source.matchAll(pattern)) if (match[1] !== void 0) found.push(match[1]);
|
|
53
|
+
return found;
|
|
54
|
+
}
|
|
55
|
+
/** A specifier a tier-2 source may use: a project file or the SDK itself. */
|
|
56
|
+
function isAllowedSpecifier(specifier) {
|
|
57
|
+
return specifier.startsWith("./") || specifier.startsWith("../") || specifier === "@fluidgrids/workflows";
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Checks sources against the store's rules (and, for tier 2, the import
|
|
61
|
+
* rule). Throws {@link TemplateCodeError} with the first problem found.
|
|
62
|
+
*/
|
|
63
|
+
function assertTemplateSources(sources, tier) {
|
|
64
|
+
if (sources.length === 0) throw new TemplateCodeError({ code: "no-files" });
|
|
65
|
+
if (sources.length > 64) throw new TemplateCodeError({
|
|
66
|
+
code: "too-many-files",
|
|
67
|
+
limit: 64
|
|
68
|
+
});
|
|
69
|
+
const seen = /* @__PURE__ */ new Set();
|
|
70
|
+
for (const file of sources) {
|
|
71
|
+
if (!isSafeTemplateSourcePath(file.path)) throw new TemplateCodeError({
|
|
72
|
+
code: "unsafe-path",
|
|
73
|
+
path: file.path
|
|
74
|
+
});
|
|
75
|
+
const folded = file.path.toLowerCase();
|
|
76
|
+
if (seen.has(folded)) throw new TemplateCodeError({
|
|
77
|
+
code: "duplicate-path",
|
|
78
|
+
path: file.path
|
|
79
|
+
});
|
|
80
|
+
seen.add(folded);
|
|
81
|
+
if (tier === "tier2" && /\.[cm]?[jt]s$/.test(file.path)) {
|
|
82
|
+
const foreign = importedSpecifiers(file.content).find((specifier) => !isAllowedSpecifier(specifier));
|
|
83
|
+
if (foreign !== void 0) throw new TemplateCodeError({
|
|
84
|
+
code: "foreign-import",
|
|
85
|
+
path: file.path,
|
|
86
|
+
specifier: foreign
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (templateSourcesBytes(sources) > 1048576) throw new TemplateCodeError({
|
|
91
|
+
code: "too-large",
|
|
92
|
+
limitBytes: TEMPLATE_SOURCES_MAX_BYTES
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* A template's code, or null when it has none or what it has is not usable
|
|
97
|
+
* (not a list of files, unsafe paths, an unknown format or tier). The store
|
|
98
|
+
* refuses such content on write; reading defensively keeps a template written
|
|
99
|
+
* before the guard, or by another client, from breaking the page.
|
|
100
|
+
*/
|
|
101
|
+
function readTemplateCode(content) {
|
|
102
|
+
if (!content || !Array.isArray(content.sources)) return null;
|
|
103
|
+
const files = [];
|
|
104
|
+
for (const entry of content.sources) {
|
|
105
|
+
if (!isRecord(entry) || typeof entry.path !== "string" || typeof entry.content !== "string") return null;
|
|
106
|
+
files.push({
|
|
107
|
+
path: entry.path,
|
|
108
|
+
contentType: typeof entry.contentType === "string" ? entry.contentType : contentTypeOf(entry.path),
|
|
109
|
+
content: entry.content
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
const format = content.sourceFormat ?? "TYPESCRIPT";
|
|
113
|
+
if (format !== "TYPESCRIPT" && format !== "PYTHON") return null;
|
|
114
|
+
const tier = content.codeTier ?? "tier1";
|
|
115
|
+
if (tier !== "tier1" && tier !== "tier2") return null;
|
|
116
|
+
try {
|
|
117
|
+
assertTemplateSources(files, "tier1");
|
|
118
|
+
} catch {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
return {
|
|
122
|
+
files,
|
|
123
|
+
format,
|
|
124
|
+
tier,
|
|
125
|
+
irHash: typeof content.sourceIrHash === "string" ? content.sourceIrHash : null
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/** The content type a project file is stored with, by its extension. */
|
|
129
|
+
function contentTypeOf(path) {
|
|
130
|
+
if (/\.[cm]?ts$/.test(path)) return "text/typescript";
|
|
131
|
+
if (/\.[cm]?js$/.test(path)) return "text/javascript";
|
|
132
|
+
if (path.endsWith(".py")) return "text/x-python";
|
|
133
|
+
if (path.endsWith(".json")) return "application/json";
|
|
134
|
+
return "text/plain";
|
|
135
|
+
}
|
|
136
|
+
/** A file name segment that is safe on every OS. */
|
|
137
|
+
function safeSegment(value) {
|
|
138
|
+
return value.toLowerCase().replace(/[^a-z0-9._-]+/g, "-").replace(/^-+|-+$/g, "");
|
|
139
|
+
}
|
|
140
|
+
/** The zip *Open as code* downloads for a template. */
|
|
141
|
+
function templateArchiveName(templateName) {
|
|
142
|
+
return `${safeSegment(templateName) || "template"}.code.zip`;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* *Open as code*: the template's project files as one zip that keeps their
|
|
146
|
+
* paths, so unpacking it gives a FluidGrids project (`fluidgrids push`
|
|
147
|
+
* reads it as it is).
|
|
148
|
+
*/
|
|
149
|
+
async function buildTemplateCodeDownload(templateName, code) {
|
|
150
|
+
const { default: JSZip } = await import("jszip");
|
|
151
|
+
const zip = new JSZip();
|
|
152
|
+
for (const file of code.files) zip.file(file.path, file.content);
|
|
153
|
+
return {
|
|
154
|
+
filename: templateArchiveName(templateName),
|
|
155
|
+
blob: await zip.generateAsync({
|
|
156
|
+
type: "blob",
|
|
157
|
+
mimeType: "application/zip"
|
|
158
|
+
})
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
/** The `source` of an `importWorkflowTemplate` for a tier-2 install. */
|
|
162
|
+
function templateImportSource(code) {
|
|
163
|
+
return {
|
|
164
|
+
format: code.format,
|
|
165
|
+
files: code.files.map((file) => ({
|
|
166
|
+
path: file.path,
|
|
167
|
+
content: file.content
|
|
168
|
+
}))
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* What `importWorkflowTemplate` installs a template from (PLAN-D D2): its
|
|
173
|
+
* sources for a tier-2 TypeScript template while code-first, durable-functions and
|
|
174
|
+
* code-templates are on (`codeTemplatesDurable`), else null, and the caller
|
|
175
|
+
* sends `definitionJson` exactly as before (tier 1, Python, no code, or a
|
|
176
|
+
* gate off).
|
|
177
|
+
*/
|
|
178
|
+
function templateInstallSource(content, codeTemplatesDurable) {
|
|
179
|
+
if (!codeTemplatesDurable) return null;
|
|
180
|
+
const code = readTemplateCode(content);
|
|
181
|
+
return code?.tier === "tier2" && code.format === "TYPESCRIPT" ? templateImportSource(code) : null;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export { readTemplateCode as n, templateInstallSource as r, buildTemplateCodeDownload as t };
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
// src/utils/template-preview.ts
|
|
3
|
+
const ICONIFY_NAME = /^[a-z0-9]+(?:-[a-z0-9]+)*:[a-z0-9]+(?:[-_][a-z0-9]+)*$/i;
|
|
4
|
+
/** True when the value is an Iconify `prefix:name` icon, not a URL. */
|
|
5
|
+
function isIconifyName(value) {
|
|
6
|
+
return ICONIFY_NAME.test(value) && !/^(https?|data|blob):/i.test(value);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* The preview for a template: its first screenshot, else its icon, which is
|
|
10
|
+
* shown as an image only when it is not an Iconify name.
|
|
11
|
+
*/
|
|
12
|
+
function templatePreview(template) {
|
|
13
|
+
const screenshot = template.screenshots?.find((shot) => typeof shot === "string" && shot.trim() !== "");
|
|
14
|
+
if (screenshot) return {
|
|
15
|
+
kind: "image",
|
|
16
|
+
src: screenshot
|
|
17
|
+
};
|
|
18
|
+
const icon = template.icon?.trim();
|
|
19
|
+
if (!icon) return { kind: "none" };
|
|
20
|
+
return isIconifyName(icon) ? {
|
|
21
|
+
kind: "icon",
|
|
22
|
+
name: icon
|
|
23
|
+
} : {
|
|
24
|
+
kind: "image",
|
|
25
|
+
src: icon
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export { templatePreview as t };
|
package/dist/templates.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as TemplatesPage } from "./TemplatesPage-
|
|
3
|
-
import { t as TemplatePreview } from "./TemplatePreview-
|
|
2
|
+
import { t as TemplatesPage } from "./TemplatesPage-CAajpJ5w.js";
|
|
3
|
+
import { t as TemplatePreview } from "./TemplatePreview-Bagja6WN.js";
|
|
4
4
|
|
|
5
5
|
export { TemplatePreview, TemplatesPage };
|