@burdenoff/fluidgrids-fe-sdk 2026.1114.5 → 2026.1114.7
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-C2SBRqab.js → AiStudioPage-DLl4ld32.js} +2 -2
- package/dist/{ExecutionDetailPage-heD4wBjg.js → ExecutionDetailPage-DxeySgR3.js} +110 -13
- package/dist/{ExecutionsListPage-Ky3TAL9U.js → ExecutionsListPage-CMrOaFKQ.js} +2 -2
- package/dist/FileDownloadUrlDocument-CVOYKcL5.js +92 -0
- package/dist/NodeUsageStatusDocument-B-XguSjm.js +531 -0
- package/dist/{OpenTemplateAsCodeButton-pepQUqje.js → OpenTemplateAsCodeButton-Cjnagq9H.js} +2 -2
- package/dist/{PaidTemplateConfirm-BJCcJh5t.js → PaidTemplateConfirm-IWOHVR6s.js} +1 -1
- package/dist/{SettingsPage-BSucNHrq.js → SettingsPage-DwA2ZjyH.js} +4 -4
- package/dist/{TaskQueuesPage-WMJz9imi.js → TaskQueuesPage-BuWQwT5I.js} +2 -2
- package/dist/{TemplateCard-Cx_eZr9q.js → TemplateCard-9Beuqm5_.js} +19 -3
- package/dist/{TemplateConfigurationModal-D2i7ZXOM.js → TemplateConfigurationModal-B_ME8M-1.js} +1 -1
- package/dist/{TemplatePreview-DwdGa8bH.js → TemplatePreview-Bi6LSeH8.js} +5 -5
- package/dist/{TemplatesPage-DF5PK7CB.js → TemplatesPage-D9fOKAn4.js} +355 -13
- package/dist/{WorkflowBuilder-CjsO7i-D.js → WorkflowBuilder-Bzx-e5lX.js} +2 -2
- package/dist/{WorkflowBuilder-DkzzbrNn.js → WorkflowBuilder-CdcGE0Mf.js} +3 -3
- package/dist/{WorkflowsList-4VADoiz_.js → WorkflowsList-CBqxxI44.js} +3 -4
- package/dist/{api-DKfMt0IX.js → api-CEzqoN5H.js} +1 -1
- package/dist/{api-CEnNq15C.js → api-o5UUDbr8.js} +1 -1
- package/dist/executions.js +2 -2
- package/dist/{flow-builder-CIV6u8y-.js → flow-builder-CbF9P7cI.js} +9 -24
- package/dist/{index-BY0V255h.d.ts → index-D10JzNP1.d.ts} +4 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +30 -27
- package/dist/{node-detail-view-DkajTGfb.js → node-detail-view-CP6sq02c.js} +7 -217
- package/dist/{node-editor-tab-body-ChLrBfKp.js → node-editor-tab-body-B6kxLf6Q.js} +1 -1
- package/dist/observability.d.ts +1 -1
- package/dist/{popover-CCJlf41J.js → popover-9gY3-2dY.js} +2 -2
- package/dist/{quick-config-panel-Bq_uF9XF.js → quick-config-panel-TGCW64qe.js} +2 -2
- package/dist/{schedule-panel-7TtPt1t_.js → schedule-panel-zrFYGtkx.js} +4 -4
- package/dist/settings.js +1 -1
- package/dist/{shared-C0LCTtyh.js → shared-mbyvDPde.js} +2 -24
- package/dist/{sidebar-node-editor-n-7ux5IN.js → sidebar-node-editor-BPg2NKzJ.js} +2 -2
- package/dist/{template-code-B3cMigJS.js → template-code-B7x-XMAm.js} +9 -2
- package/dist/templates.js +2 -2
- package/dist/typed-calls-BqokR321.js +26 -0
- package/dist/{WorkflowEditLeaseStatusDocument-Dp62med3.js → use-workflow-code-editor-CBOkjntt.js} +216 -90
- package/dist/{useAgentDefinitions-Daa3fGVg.js → useAgentDefinitions-9pmnEpb8.js} +1 -1
- package/dist/useConnections-CmnwGk09.js +439 -0
- package/dist/{useWorkflowCodeExport-lRmbjY49.js → useWorkflowCodeExport-ChAzmhi6.js} +78 -114
- package/dist/workflow-builder.js +2 -2
- package/dist/workflow-description-ReGwCZXS.js +123 -0
- package/dist/workflow-pages.d.ts +1 -1
- package/dist/workflow-pages.js +9 -9
- package/dist/{workflow-code-transfer-BsLPUrKP.js → workflow-transfer-CktP7o1c.js} +103 -1
- package/dist/workflows-list.js +1 -1
- package/package.json +1 -1
- package/dist/QuotaExhaustedDialog-YjKgRTmu.js +0 -55
- package/dist/useConnections-BlB0gbOB.js +0 -931
- package/dist/workflow-transfer-CQnQC-ke.js +0 -104
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
|
|
3
3
|
import { h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, s as useDuplicateWorkflow } from "./useWorkflows-BrqrVT8h.js";
|
|
4
|
-
import { i as useTemplateImportFlow, l as useWorkflowTemplates, r as isPaidTemplate, t as TemplateCard } from "./TemplateCard-
|
|
5
|
-
import { nL as WorkflowStatus } from "./graphql-types-dS3Fk9Z5.js";
|
|
4
|
+
import { i as useTemplateImportFlow, l as useWorkflowTemplates, r as isPaidTemplate, t as TemplateCard, v as storeContextHeaders } from "./TemplateCard-9Beuqm5_.js";
|
|
5
|
+
import { OI as WorkflowExportFormat, nL as WorkflowStatus } from "./graphql-types-dS3Fk9Z5.js";
|
|
6
6
|
import { i as SdkPermissionButton, t as FLUIDGRIDS_PERMISSIONS } from "./constants-65QV61nQ.js";
|
|
7
|
-
import {
|
|
7
|
+
import { i as QuotaExhaustedDialog, t as fetchWorkflowCodeExport } from "./useWorkflowCodeExport-ChAzmhi6.js";
|
|
8
8
|
import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
|
|
9
9
|
import { t as FluidGridsContext, un as useFluidGridsAnalytics } from "./FluidGridsProvider-C-WGQwuT.js";
|
|
10
10
|
import { a as emitTemplateUsed } from "./fluidgridsEvents-Dm5CaHtr.js";
|
|
@@ -12,14 +12,19 @@ import { n as useFluidGridsPageControls } from "./pageControlsBridge-0pX9s-3k.js
|
|
|
12
12
|
import { r as templatesControls } from "./pageControlSpecs-DZJ9K37m.js";
|
|
13
13
|
import { c as isQuotaExhaustedFailure, t as BILLING_PLANS_PATH } from "./quota-Cdt8yz7N.js";
|
|
14
14
|
import { t as FluidGridsDocsLink } from "./FluidGridsDocsLink-JxkBpOeb.js";
|
|
15
|
+
import { h as usePhaseDFlags } from "./feature-flags-B_b8PJ6Z.js";
|
|
16
|
+
import { t as fetchWorkflowCodeSource } from "./use-workflow-code-editor-CBOkjntt.js";
|
|
17
|
+
import { t as fetchConnectionNames } from "./useConnections-CmnwGk09.js";
|
|
18
|
+
import { m as isLosslessReport } from "./workflow-transfer-CktP7o1c.js";
|
|
19
|
+
import { a as contentTypeOf, n as TemplateCodeError, o as isTier2Definition, r as assertTemplateSources, t as TEMPLATE_SOURCES_MAX_BYTES } from "./template-code-B7x-XMAm.js";
|
|
15
20
|
import { t as useGlobalStoreClient } from "./useGlobalStoreClient-BcwWGtm7.js";
|
|
21
|
+
import { r as getFluidGridsConfig } from "./config-X97zrIvn.js";
|
|
16
22
|
import { o as throwIfResultError, t as describeOperationError } from "./errors-xPZ-IbQd.js";
|
|
17
23
|
import { t as NodeTypeIcon } from "./node-type-icon-DEAztACh.js";
|
|
18
24
|
import { n as formatRunVersion } from "./run-display-UjLAoYqQ.js";
|
|
19
25
|
import { n as useNavigationV2 } from "./useNavigationV2-C2WeqN7d.js";
|
|
20
26
|
import { t as TechnicalDetails } from "./TechnicalDetails-r5JXr1jZ.js";
|
|
21
|
-
import { t as PaidTemplateConfirm } from "./PaidTemplateConfirm-
|
|
22
|
-
import { r as getFluidGridsConfig } from "./config-X97zrIvn.js";
|
|
27
|
+
import { t as PaidTemplateConfirm } from "./PaidTemplateConfirm-IWOHVR6s.js";
|
|
23
28
|
import { t as cn } from "./cn-QqidFIgr.js";
|
|
24
29
|
import { useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
25
30
|
import { useNavigate } from "react-router";
|
|
@@ -28,7 +33,7 @@ import { Icon } from "@iconify/react";
|
|
|
28
33
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
29
34
|
import { toast } from "sonner";
|
|
30
35
|
import { gql } from "@apollo/client";
|
|
31
|
-
import { Badge, Card, CardHeader, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton, Textarea } from "@burdenoff/fe-libs/ui";
|
|
36
|
+
import { Badge, Card, CardHeader, Checkbox, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, Input, Label, Select, SelectContent, SelectItem, SelectTrigger, SelectValue, Skeleton, Textarea } from "@burdenoff/fe-libs/ui";
|
|
32
37
|
import { Button as Button$1 } from "@burdenoff/fe-libs/button";
|
|
33
38
|
import { v4 } from "uuid";
|
|
34
39
|
|
|
@@ -270,6 +275,56 @@ const SubmitWorkflowTemplateDocument = {
|
|
|
270
275
|
"arguments": [],
|
|
271
276
|
"directives": []
|
|
272
277
|
},
|
|
278
|
+
{
|
|
279
|
+
"kind": "Field",
|
|
280
|
+
"name": {
|
|
281
|
+
"kind": "Name",
|
|
282
|
+
"value": "code"
|
|
283
|
+
},
|
|
284
|
+
"arguments": [],
|
|
285
|
+
"directives": [],
|
|
286
|
+
"selectionSet": {
|
|
287
|
+
"kind": "SelectionSet",
|
|
288
|
+
"selections": [
|
|
289
|
+
{
|
|
290
|
+
"kind": "Field",
|
|
291
|
+
"name": {
|
|
292
|
+
"kind": "Name",
|
|
293
|
+
"value": "tier"
|
|
294
|
+
},
|
|
295
|
+
"arguments": [],
|
|
296
|
+
"directives": []
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"kind": "Field",
|
|
300
|
+
"name": {
|
|
301
|
+
"kind": "Name",
|
|
302
|
+
"value": "format"
|
|
303
|
+
},
|
|
304
|
+
"arguments": [],
|
|
305
|
+
"directives": []
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"kind": "Field",
|
|
309
|
+
"name": {
|
|
310
|
+
"kind": "Name",
|
|
311
|
+
"value": "fileCount"
|
|
312
|
+
},
|
|
313
|
+
"arguments": [],
|
|
314
|
+
"directives": []
|
|
315
|
+
},
|
|
316
|
+
{
|
|
317
|
+
"kind": "Field",
|
|
318
|
+
"name": {
|
|
319
|
+
"kind": "Name",
|
|
320
|
+
"value": "bytes"
|
|
321
|
+
},
|
|
322
|
+
"arguments": [],
|
|
323
|
+
"directives": []
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
}
|
|
327
|
+
},
|
|
273
328
|
{
|
|
274
329
|
"kind": "Field",
|
|
275
330
|
"name": {
|
|
@@ -708,6 +763,56 @@ const MyWorkflowTemplateSubmissionsDocument = {
|
|
|
708
763
|
"arguments": [],
|
|
709
764
|
"directives": []
|
|
710
765
|
},
|
|
766
|
+
{
|
|
767
|
+
"kind": "Field",
|
|
768
|
+
"name": {
|
|
769
|
+
"kind": "Name",
|
|
770
|
+
"value": "code"
|
|
771
|
+
},
|
|
772
|
+
"arguments": [],
|
|
773
|
+
"directives": [],
|
|
774
|
+
"selectionSet": {
|
|
775
|
+
"kind": "SelectionSet",
|
|
776
|
+
"selections": [
|
|
777
|
+
{
|
|
778
|
+
"kind": "Field",
|
|
779
|
+
"name": {
|
|
780
|
+
"kind": "Name",
|
|
781
|
+
"value": "tier"
|
|
782
|
+
},
|
|
783
|
+
"arguments": [],
|
|
784
|
+
"directives": []
|
|
785
|
+
},
|
|
786
|
+
{
|
|
787
|
+
"kind": "Field",
|
|
788
|
+
"name": {
|
|
789
|
+
"kind": "Name",
|
|
790
|
+
"value": "format"
|
|
791
|
+
},
|
|
792
|
+
"arguments": [],
|
|
793
|
+
"directives": []
|
|
794
|
+
},
|
|
795
|
+
{
|
|
796
|
+
"kind": "Field",
|
|
797
|
+
"name": {
|
|
798
|
+
"kind": "Name",
|
|
799
|
+
"value": "fileCount"
|
|
800
|
+
},
|
|
801
|
+
"arguments": [],
|
|
802
|
+
"directives": []
|
|
803
|
+
},
|
|
804
|
+
{
|
|
805
|
+
"kind": "Field",
|
|
806
|
+
"name": {
|
|
807
|
+
"kind": "Name",
|
|
808
|
+
"value": "bytes"
|
|
809
|
+
},
|
|
810
|
+
"arguments": [],
|
|
811
|
+
"directives": []
|
|
812
|
+
}
|
|
813
|
+
]
|
|
814
|
+
}
|
|
815
|
+
},
|
|
711
816
|
{
|
|
712
817
|
"kind": "Field",
|
|
713
818
|
"name": {
|
|
@@ -758,11 +863,18 @@ const TEMPLATE_STORE_CATEGORIES = [
|
|
|
758
863
|
* which already masks literal secrets. The store removes connection bindings,
|
|
759
864
|
* pinned run data and any remaining secrets, builds the manifest and puts the
|
|
760
865
|
* template into review; a store admin approves or rejects it.
|
|
866
|
+
*
|
|
867
|
+
* With `code` the template also carries the workflow as code (G22). The
|
|
868
|
+
* workspace context goes with the request, because the store checks the
|
|
869
|
+
* workspace's code-first flags before it accepts code.
|
|
761
870
|
*/
|
|
762
871
|
function usePublishToStore() {
|
|
763
872
|
const [publishing, setPublishing] = useState(false);
|
|
764
873
|
const [error, setError] = useState(null);
|
|
765
874
|
const globalClient = useGlobalStoreClient();
|
|
875
|
+
const context = useContext(FluidGridsContext);
|
|
876
|
+
const workspaceId = context?.workspaceId ?? getFluidGridsConfig().workspaceId;
|
|
877
|
+
const organizationId = context?.organizationId;
|
|
766
878
|
return {
|
|
767
879
|
publishToStore: useCallback(async (input) => {
|
|
768
880
|
setPublishing(true);
|
|
@@ -785,8 +897,14 @@ function usePublishToStore() {
|
|
|
785
897
|
authorName: input.authorName?.trim() || void 0,
|
|
786
898
|
difficultyLevel: input.difficultyLevel,
|
|
787
899
|
estimatedTimeMinutes: input.estimatedTimeMinutes,
|
|
788
|
-
notes: input.notes?.trim() || void 0
|
|
789
|
-
|
|
900
|
+
notes: input.notes?.trim() || void 0,
|
|
901
|
+
code: input.code
|
|
902
|
+
} },
|
|
903
|
+
context: { headers: storeContextHeaders({
|
|
904
|
+
organizationId,
|
|
905
|
+
workspaceId,
|
|
906
|
+
workspaceToken: getFluidGridsConfig().workspaceToken
|
|
907
|
+
}) }
|
|
790
908
|
})).data?.submitWorkflowTemplate;
|
|
791
909
|
if (!submission) throw new Error("The store did not return the submitted template");
|
|
792
910
|
return {
|
|
@@ -805,7 +923,11 @@ function usePublishToStore() {
|
|
|
805
923
|
} finally {
|
|
806
924
|
setPublishing(false);
|
|
807
925
|
}
|
|
808
|
-
}, [
|
|
926
|
+
}, [
|
|
927
|
+
globalClient,
|
|
928
|
+
organizationId,
|
|
929
|
+
workspaceId
|
|
930
|
+
]),
|
|
809
931
|
publishing,
|
|
810
932
|
error
|
|
811
933
|
};
|
|
@@ -863,6 +985,176 @@ function useTemplateSubmissions(enabled = true, limit = 50) {
|
|
|
863
985
|
};
|
|
864
986
|
}
|
|
865
987
|
|
|
988
|
+
// src/hooks/store/templateCode.ts
|
|
989
|
+
/**
|
|
990
|
+
* *Include code* when a workflow is published as a community template
|
|
991
|
+
* (code-first gap G22, BOFF-14107, spec code-first/07 section 9).
|
|
992
|
+
*
|
|
993
|
+
* Collects the code `submitWorkflowTemplate` takes in `input.code`:
|
|
994
|
+
*
|
|
995
|
+
* - A canvas workflow (tier 1) is lifted to TypeScript by the service
|
|
996
|
+
* (`exportWorkflow`). Connections are written by name (the names of the
|
|
997
|
+
* author's saved connections), never by id, and pinned data is left out, so
|
|
998
|
+
* the code carries nothing the store removes from the definition. Only a
|
|
999
|
+
* lossless lift is published, so installing the code gives back the same
|
|
1000
|
+
* workflow.
|
|
1001
|
+
* - A durable function (tier 2) attaches its project files
|
|
1002
|
+
* (`workflowCodeSource`, vendored files excluded), TypeScript or Python.
|
|
1003
|
+
* TypeScript files may import only project files and
|
|
1004
|
+
* `@fluidgrids/workflows`.
|
|
1005
|
+
*
|
|
1006
|
+
* The store's rules (64 files, 1 MiB, safe and unique paths) are checked here
|
|
1007
|
+
* first, so a refusal is explained before anything is sent. The store checks
|
|
1008
|
+
* them again, and also refuses code that carries a secret.
|
|
1009
|
+
*/
|
|
1010
|
+
/** Thrown when a flag *Include code* needs is off (fails closed). */
|
|
1011
|
+
var CodeTemplatesDisabledError = class extends Error {
|
|
1012
|
+
constructor() {
|
|
1013
|
+
super("Publishing a template with its code is not enabled here");
|
|
1014
|
+
this.name = "CodeTemplatesDisabledError";
|
|
1015
|
+
}
|
|
1016
|
+
};
|
|
1017
|
+
function isRecord(value) {
|
|
1018
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1019
|
+
}
|
|
1020
|
+
/** Keys that bind a node to a saved connection (as global-store-svc reads them). */
|
|
1021
|
+
const CONNECTION_KEYS = /* @__PURE__ */ new Set([
|
|
1022
|
+
"connectionId",
|
|
1023
|
+
"credentialId",
|
|
1024
|
+
"credentialsId"
|
|
1025
|
+
]);
|
|
1026
|
+
const CONNECTION_ID_FIELDS = [
|
|
1027
|
+
"id",
|
|
1028
|
+
"connectionId",
|
|
1029
|
+
"credentialId",
|
|
1030
|
+
"credentialsId"
|
|
1031
|
+
];
|
|
1032
|
+
/** Deepest nesting walked; a definition the store accepts is never deeper. */
|
|
1033
|
+
const MAX_DEPTH = 64;
|
|
1034
|
+
/**
|
|
1035
|
+
* The saved-connection ids a definition refers to: values of `connectionId`,
|
|
1036
|
+
* `credentialId` and `credentialsId`, and the entries of `connections`
|
|
1037
|
+
* lists (an id, or an object's id field).
|
|
1038
|
+
*/
|
|
1039
|
+
function definitionConnectionIds(definition) {
|
|
1040
|
+
const found = /* @__PURE__ */ new Set();
|
|
1041
|
+
const visit = (value, depth) => {
|
|
1042
|
+
if (depth > MAX_DEPTH) return;
|
|
1043
|
+
if (Array.isArray(value)) {
|
|
1044
|
+
for (const item of value) visit(item, depth + 1);
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
1047
|
+
if (!isRecord(value)) return;
|
|
1048
|
+
for (const [key, child] of Object.entries(value)) {
|
|
1049
|
+
if (CONNECTION_KEYS.has(key) && typeof child === "string" && child) found.add(child);
|
|
1050
|
+
else if (key === "connections" && Array.isArray(child)) {
|
|
1051
|
+
for (const entry of child) if (typeof entry === "string" && entry) found.add(entry);
|
|
1052
|
+
else if (isRecord(entry)) for (const field of CONNECTION_ID_FIELDS) {
|
|
1053
|
+
const id = entry[field];
|
|
1054
|
+
if (typeof id === "string" && id) found.add(id);
|
|
1055
|
+
}
|
|
1056
|
+
}
|
|
1057
|
+
visit(child, depth + 1);
|
|
1058
|
+
}
|
|
1059
|
+
};
|
|
1060
|
+
visit(definition, 0);
|
|
1061
|
+
return [...found];
|
|
1062
|
+
}
|
|
1063
|
+
/** The language of a tier-2 definition's code block. */
|
|
1064
|
+
function tier2Format(definitionJson) {
|
|
1065
|
+
const code = isRecord(definitionJson) ? definitionJson.code : void 0;
|
|
1066
|
+
return (isRecord(code) ? code.language : void 0) === "python" ? "PYTHON" : "TYPESCRIPT";
|
|
1067
|
+
}
|
|
1068
|
+
async function collectTier2(workflow) {
|
|
1069
|
+
const source = await fetchWorkflowCodeSource(workflow.workflowKey, workflow.version);
|
|
1070
|
+
if (!source || source.files.length === 0) throw new TemplateCodeError({ code: "no-files" });
|
|
1071
|
+
const files = source.files.map((file) => ({
|
|
1072
|
+
path: file.path,
|
|
1073
|
+
contentType: contentTypeOf(file.path),
|
|
1074
|
+
content: file.content
|
|
1075
|
+
}));
|
|
1076
|
+
assertTemplateSources(files, "tier2");
|
|
1077
|
+
return {
|
|
1078
|
+
tier: "TIER2",
|
|
1079
|
+
format: tier2Format(workflow.definitionJson),
|
|
1080
|
+
files
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
async function collectTier1(workflow) {
|
|
1084
|
+
const connectionIds = definitionConnectionIds(workflow.definitionJson);
|
|
1085
|
+
const connectionNameMap = await fetchConnectionNames(connectionIds);
|
|
1086
|
+
const exported = await fetchWorkflowCodeExport({
|
|
1087
|
+
workflowKey: workflow.workflowKey,
|
|
1088
|
+
version: workflow.version,
|
|
1089
|
+
format: "TYPESCRIPT",
|
|
1090
|
+
options: {
|
|
1091
|
+
connectionNameMap,
|
|
1092
|
+
connectionNames: true,
|
|
1093
|
+
includeLayout: true,
|
|
1094
|
+
includePinnedData: false
|
|
1095
|
+
}
|
|
1096
|
+
});
|
|
1097
|
+
if (!isLosslessReport(exported.fidelity)) throw new TemplateCodeError({ code: "lossy" });
|
|
1098
|
+
const files = exported.files.map((file) => ({
|
|
1099
|
+
path: file.path,
|
|
1100
|
+
contentType: file.contentType || contentTypeOf(file.path),
|
|
1101
|
+
content: file.content ?? ""
|
|
1102
|
+
}));
|
|
1103
|
+
if (connectionIds.find((id) => !connectionNameMap[id] && files.some((file) => file.content.includes(id))) !== void 0) throw new TemplateCodeError({ code: "unnamed-connection" });
|
|
1104
|
+
assertTemplateSources(files, "tier1");
|
|
1105
|
+
return {
|
|
1106
|
+
tier: "TIER1",
|
|
1107
|
+
format: "TYPESCRIPT",
|
|
1108
|
+
files,
|
|
1109
|
+
sourceIrHash: exported.irHash
|
|
1110
|
+
};
|
|
1111
|
+
}
|
|
1112
|
+
/** Whether *Include code* can be offered for a workflow with these flags. */
|
|
1113
|
+
function canIncludeTemplateCode(definitionJson, flags) {
|
|
1114
|
+
return isTier2Definition(definitionJson) ? flags.codeTemplatesDurable : flags.codeTemplates;
|
|
1115
|
+
}
|
|
1116
|
+
/**
|
|
1117
|
+
* The code to publish with a workflow version. Throws
|
|
1118
|
+
* {@link CodeTemplatesDisabledError} when a needed flag is off and
|
|
1119
|
+
* {@link TemplateCodeError} when the code cannot be published (a lossy lift,
|
|
1120
|
+
* a connection without a name, no files, or a store rule broken).
|
|
1121
|
+
*/
|
|
1122
|
+
async function collectTemplateCode(workflow, flags) {
|
|
1123
|
+
if (!canIncludeTemplateCode(workflow.definitionJson, flags)) throw new CodeTemplatesDisabledError();
|
|
1124
|
+
return isTier2Definition(workflow.definitionJson) ? collectTier2(workflow) : collectTier1(workflow);
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// src/modules/templates/utils/template-code-messages.ts
|
|
1128
|
+
/**
|
|
1129
|
+
* Messages for *Include code* refusals in the publish dialog (G22,
|
|
1130
|
+
* BOFF-14107). Each one tells the author what to change, or that they can
|
|
1131
|
+
* untick *Include code* and publish the definition only.
|
|
1132
|
+
*/
|
|
1133
|
+
/**
|
|
1134
|
+
* The message for an error raised while collecting a template's code, or
|
|
1135
|
+
* null when the error is not a code refusal (the caller then shows the
|
|
1136
|
+
* error's own message).
|
|
1137
|
+
*/
|
|
1138
|
+
function templateCodeErrorMessage(error, tr) {
|
|
1139
|
+
if (error instanceof CodeTemplatesDisabledError) return tr("fluidgrids.templates.publish.code.disabled", "Publishing a template with its code is not turned on for this workspace. Untick Include code to publish the workflow without it.");
|
|
1140
|
+
if (!(error instanceof TemplateCodeError)) return null;
|
|
1141
|
+
const { problem } = error;
|
|
1142
|
+
switch (problem.code) {
|
|
1143
|
+
case "lossy": return tr("fluidgrids.templates.publish.code.lossy", "This workflow cannot be turned into code without losing something (see the Code view for what). Untick Include code to publish it without code.");
|
|
1144
|
+
case "unnamed-connection": return tr("fluidgrids.templates.publish.code.unnamedConnection", "A node uses a connection that no longer exists, so its code would carry the connection's id. Pick a saved connection for it, save, and try again.");
|
|
1145
|
+
case "no-files": return tr("fluidgrids.templates.publish.code.noFiles", "This version has no code files to include. Save the workflow's code and try again.");
|
|
1146
|
+
case "too-large": return tr("fluidgrids.templates.publish.code.tooLarge", "The code is larger than the store allows ({{limit}} KB).", { limit: Math.round(TEMPLATE_SOURCES_MAX_BYTES / 1024) });
|
|
1147
|
+
case "too-many-files": return tr("fluidgrids.templates.publish.code.tooManyFiles", "The code has more files than the store allows ({{limit}}).", { limit: 64 });
|
|
1148
|
+
case "unsafe-path": return tr("fluidgrids.templates.publish.code.unsafePath", "The file {{path}} has a path the store does not accept.", { path: problem.path });
|
|
1149
|
+
case "duplicate-path": return tr("fluidgrids.templates.publish.code.duplicatePath", "Two files share the path {{path}}.", { path: problem.path });
|
|
1150
|
+
case "foreign-import": return tr("fluidgrids.templates.publish.code.foreignImport", "{{path}} imports {{specifier}}. Template code may import only its own files and @fluidgrids/workflows.", {
|
|
1151
|
+
path: problem.path,
|
|
1152
|
+
specifier: problem.specifier
|
|
1153
|
+
});
|
|
1154
|
+
case "python-tier2": return tr("fluidgrids.templates.publish.code.pythonTier2", "Python code cannot be installed from a template.");
|
|
1155
|
+
}
|
|
1156
|
+
}
|
|
1157
|
+
|
|
866
1158
|
// src/modules/templates/utils/template-categories.ts
|
|
867
1159
|
/** English labels for the store's template categories (BOFF-4316). */
|
|
868
1160
|
const TEMPLATE_CATEGORY_LABELS = {
|
|
@@ -915,7 +1207,11 @@ function parseTemplateTags(value) {
|
|
|
915
1207
|
* definition. The store removes the author's connection bindings, pinned run
|
|
916
1208
|
* data and literal secrets before keeping a copy, and a store admin reviews the
|
|
917
1209
|
* template before it is listed. Passing `resubmit` updates one of the author's
|
|
918
|
-
* rejected or withdrawn templates instead of creating
|
|
1210
|
+
* rejected or withdrawn templates instead of creating one.
|
|
1211
|
+
*
|
|
1212
|
+
* *Include code* (G22, shown when the workspace has code templates on) also
|
|
1213
|
+
* publishes the workflow as code, so people who install the template can
|
|
1214
|
+
* open it as a code project. The store refuses code that carries a secret.
|
|
919
1215
|
*/
|
|
920
1216
|
const DIFFICULTIES = [
|
|
921
1217
|
"easy",
|
|
@@ -930,6 +1226,10 @@ function PublishTemplateDialog({ open, onOpenChange, workflow, resubmit, onSubmi
|
|
|
930
1226
|
const tr = useTr();
|
|
931
1227
|
const { publishToStore, publishing } = usePublishToStore();
|
|
932
1228
|
const { getWorkflow } = useLazyWorkflowDefinition();
|
|
1229
|
+
const phaseD = usePhaseDFlags();
|
|
1230
|
+
const [includeCode, setIncludeCode] = useState(false);
|
|
1231
|
+
const [collectingCode, setCollectingCode] = useState(false);
|
|
1232
|
+
const busy = publishing || collectingCode;
|
|
933
1233
|
const [name, setName] = useState("");
|
|
934
1234
|
const [description, setDescription] = useState("");
|
|
935
1235
|
const [longDescription, setLongDescription] = useState("");
|
|
@@ -949,6 +1249,7 @@ function PublishTemplateDialog({ open, onOpenChange, workflow, resubmit, onSubmi
|
|
|
949
1249
|
setAuthorName(resubmit?.authorName ?? "");
|
|
950
1250
|
setDifficulty("medium");
|
|
951
1251
|
setNotes("");
|
|
1252
|
+
setIncludeCode(false);
|
|
952
1253
|
setError(null);
|
|
953
1254
|
}, [
|
|
954
1255
|
open,
|
|
@@ -971,8 +1272,21 @@ function PublishTemplateDialog({ open, onOpenChange, workflow, resubmit, onSubmi
|
|
|
971
1272
|
setError(tr("fluidgrids.templates.publish.definitionMissing", "Could not read this workflow's definition. Save it and try again."));
|
|
972
1273
|
return;
|
|
973
1274
|
}
|
|
1275
|
+
let code;
|
|
1276
|
+
if (includeCode && phaseD.codeTemplates) {
|
|
1277
|
+
setCollectingCode(true);
|
|
1278
|
+
try {
|
|
1279
|
+
code = await collectTemplateCode(current, phaseD);
|
|
1280
|
+
} catch (err) {
|
|
1281
|
+
setError(templateCodeErrorMessage(err, tr) ?? (err instanceof Error ? err.message : tr("fluidgrids.templates.publish.code.failed", "Could not read this workflow's code.")));
|
|
1282
|
+
return;
|
|
1283
|
+
} finally {
|
|
1284
|
+
setCollectingCode(false);
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
974
1287
|
const result = await publishToStore({
|
|
975
1288
|
workflow: current,
|
|
1289
|
+
code,
|
|
976
1290
|
productId: resubmit?.id,
|
|
977
1291
|
name,
|
|
978
1292
|
description,
|
|
@@ -1111,6 +1425,26 @@ function PublishTemplateDialog({ open, onOpenChange, workflow, resubmit, onSubmi
|
|
|
1111
1425
|
onChange: (e) => setNotes(e.target.value)
|
|
1112
1426
|
})]
|
|
1113
1427
|
}),
|
|
1428
|
+
phaseD.codeTemplates && /* @__PURE__ */ jsxs("div", {
|
|
1429
|
+
className: "space-y-1",
|
|
1430
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
1431
|
+
className: "flex items-center gap-2",
|
|
1432
|
+
children: [/* @__PURE__ */ jsx(Checkbox, {
|
|
1433
|
+
id: "publish-template-include-code",
|
|
1434
|
+
"data-testid": "publish-template-include-code",
|
|
1435
|
+
checked: includeCode,
|
|
1436
|
+
disabled: busy,
|
|
1437
|
+
onCheckedChange: (on) => setIncludeCode(on === true)
|
|
1438
|
+
}), /* @__PURE__ */ jsx(Label, {
|
|
1439
|
+
htmlFor: "publish-template-include-code",
|
|
1440
|
+
className: "text-sm",
|
|
1441
|
+
children: tr("fluidgrids.templates.publish.includeCodeLabel", "Include code")
|
|
1442
|
+
})]
|
|
1443
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
1444
|
+
className: "text-xs text-text-secondary",
|
|
1445
|
+
children: tr("fluidgrids.templates.publish.includeCodeHint", "People who install the template can open it as a code project. Code that contains a secret is refused.")
|
|
1446
|
+
})]
|
|
1447
|
+
}),
|
|
1114
1448
|
error && /* @__PURE__ */ jsx("p", {
|
|
1115
1449
|
role: "alert",
|
|
1116
1450
|
className: "text-sm text-[var(--color-status-error-text)]",
|
|
@@ -1122,13 +1456,13 @@ function PublishTemplateDialog({ open, onOpenChange, workflow, resubmit, onSubmi
|
|
|
1122
1456
|
/* @__PURE__ */ jsxs(DialogFooter, { children: [/* @__PURE__ */ jsx(Button$1, {
|
|
1123
1457
|
variant: "outline",
|
|
1124
1458
|
onClick: () => onOpenChange(false),
|
|
1125
|
-
disabled:
|
|
1459
|
+
disabled: busy,
|
|
1126
1460
|
children: tr("fluidgrids.templates.publish.cancel", "Cancel")
|
|
1127
1461
|
}), /* @__PURE__ */ jsxs(Button$1, {
|
|
1128
1462
|
onClick: () => void submit(),
|
|
1129
|
-
disabled:
|
|
1463
|
+
disabled: busy || !workflow,
|
|
1130
1464
|
"data-testid": "publish-template-submit",
|
|
1131
|
-
children: [
|
|
1465
|
+
children: [busy ? /* @__PURE__ */ jsx(Icon, {
|
|
1132
1466
|
icon: "mdi:loading",
|
|
1133
1467
|
width: 14,
|
|
1134
1468
|
className: "mr-1.5 animate-spin"
|
|
@@ -1295,6 +1629,14 @@ function MySubmissionsPanel({ onResubmit }) {
|
|
|
1295
1629
|
" ",
|
|
1296
1630
|
tr("fluidgrids.templates.submissions.downloads", "{{count}} imports", { count: submission.downloads })
|
|
1297
1631
|
] }),
|
|
1632
|
+
submission.code && /* @__PURE__ */ jsxs("span", {
|
|
1633
|
+
"data-testid": "my-submission-code",
|
|
1634
|
+
children: [
|
|
1635
|
+
"·",
|
|
1636
|
+
" ",
|
|
1637
|
+
tr("fluidgrids.templates.submissions.includesCode", "includes code ({{count}} files)", { count: submission.code.fileCount })
|
|
1638
|
+
]
|
|
1639
|
+
}),
|
|
1298
1640
|
submission.sourceWorkflowKey && /* @__PURE__ */ jsxs("span", {
|
|
1299
1641
|
className: "truncate",
|
|
1300
1642
|
children: [
|
|
@@ -3,10 +3,10 @@ import { fn as useCanvasEdges, n as FluidGridsProvider } from "./FluidGridsProvi
|
|
|
3
3
|
import { A as useFlowStore } from "./node-operation-selection-DHbtGNrG.js";
|
|
4
4
|
import { t as Button } from "./button-DG7y_FVJ.js";
|
|
5
5
|
import { t as Input } from "./input-ChT6Q-Pr.js";
|
|
6
|
-
import {
|
|
6
|
+
import { y as Card } from "./TemplateCard-9Beuqm5_.js";
|
|
7
7
|
import { t as cn } from "./cn-QqidFIgr.js";
|
|
8
8
|
import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
|
|
9
|
-
import { m as FluidGridsMark, p as useNodeSelectedEvent } from "./flow-builder-
|
|
9
|
+
import { m as FluidGridsMark, p as useNodeSelectedEvent } from "./flow-builder-CbF9P7cI.js";
|
|
10
10
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
11
11
|
import { Background, Controls, Handle, MarkerType, MiniMap, Position, ReactFlow, ReactFlowProvider, useReactFlow } from "@xyflow/react";
|
|
12
12
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
|
|
3
|
-
import { d as releaseLeaseKeptForReload, f as useWorkflowReloadStore, t as FlowBuilderPage } from "./flow-builder-
|
|
3
|
+
import { d as releaseLeaseKeptForReload, f as useWorkflowReloadStore, t as FlowBuilderPage } from "./flow-builder-CbF9P7cI.js";
|
|
4
4
|
import { n as registerLiveCanvasHandler } from "./liveCanvas-D5ytXDp8.js";
|
|
5
5
|
import { r as getFluidGridsConfig } from "./config-X97zrIvn.js";
|
|
6
6
|
import { n as getFluidGridsClient } from "./client-Ctl4jmY3.js";
|
|
@@ -11,11 +11,11 @@ import { $t as workflowFingerprint, Jt as codeBuildIdOf, M as createConfiguredNo
|
|
|
11
11
|
import { A as useFlowStore } from "./node-operation-selection-DHbtGNrG.js";
|
|
12
12
|
import { t as canvasFromDefinition } from "./definition-canvas-DL25_6NH.js";
|
|
13
13
|
import { l as useLazyWorkflowDefinition, n as useCreateWorkflow } from "./useWorkflows-BrqrVT8h.js";
|
|
14
|
-
import { _ as useInstalledNodes, a as buildNodeCheck, o as buildRequiredNodeTypes, s as getWorkflowNodeTypes } from "./TemplateCard-
|
|
14
|
+
import { _ as useInstalledNodes, a as buildNodeCheck, o as buildRequiredNodeTypes, s as getWorkflowNodeTypes } from "./TemplateCard-9Beuqm5_.js";
|
|
15
15
|
import { r as mergeStickyNotes } from "./sticky-notes-23j-wL6Q.js";
|
|
16
16
|
import { c as withoutGuidedTourIntent, l as decideMissingWorkflow, o as isGuidedTourIntent, s as pickGuidedTour, u as isCreateIntent } from "./firstWorkflow-C_h0KMB2.js";
|
|
17
17
|
import { t as BILLING_PLANS_PATH } from "./quota-Cdt8yz7N.js";
|
|
18
|
-
import {
|
|
18
|
+
import { o as CreateWorkflowRefusalDialog } from "./workflow-description-ReGwCZXS.js";
|
|
19
19
|
import { Suspense, lazy, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
20
20
|
import { useLocation, useNavigate, useParams } from "react-router";
|
|
21
21
|
import { Icon } from "@iconify/react";
|
|
@@ -2,19 +2,18 @@
|
|
|
2
2
|
import { t as __exportAll } from "./rolldown-runtime-hDbaFkMy.js";
|
|
3
3
|
import { c as useImportWorkflow, h as useWorkflowDefinitions, l as useLazyWorkflowDefinition, n as useCreateWorkflow, o as useDeleteWorkflow, s as useDuplicateWorkflow, u as usePreviewN8nImport } from "./useWorkflows-BrqrVT8h.js";
|
|
4
4
|
import { St as createThenOpen, t as FluidGridsContext } from "./FluidGridsProvider-C-WGQwuT.js";
|
|
5
|
-
import { a as
|
|
5
|
+
import { a as workflowDescriptionCharactersLeft, i as visibleWorkflowDescription, o as CreateWorkflowRefusalDialog, r as saveWorkflowDescription, t as commitWorkflowDescription } from "./workflow-description-ReGwCZXS.js";
|
|
6
6
|
import { c as isQuotaExhaustedFailure, t as BILLING_PLANS_PATH } from "./quota-Cdt8yz7N.js";
|
|
7
7
|
import { A as useFlowStore } from "./node-operation-selection-DHbtGNrG.js";
|
|
8
8
|
import { a as SdkPermissionGate, i as SdkPermissionButton, s as useFluidGridsPermission, t as FLUIDGRIDS_PERMISSIONS } from "./constants-65QV61nQ.js";
|
|
9
|
-
import {
|
|
9
|
+
import { i as QuotaExhaustedDialog, n as useExportWorkflowAs } from "./useWorkflowCodeExport-ChAzmhi6.js";
|
|
10
10
|
import { r as useTr } from "./TranslationBridge-Da-TPgQm.js";
|
|
11
11
|
import { a as isExecutionMode, i as isAutonomyLevel, n as EXECUTION_MODES, o as useAutonomyLevelCopy, r as EXECUTION_MODE_ICONS, s as useExecutionModeCopy } from "./run-mode-Bu_pgjeM.js";
|
|
12
12
|
import { OI as WorkflowExportFormat, vI as WorkflowAccessFilter } from "./graphql-types-dS3Fk9Z5.js";
|
|
13
|
-
import {
|
|
13
|
+
import { S as typeScriptModuleFile, a as ImportSourceError, c as assertImportByteSize, f as importAcceptAttribute, i as CODE_EXPORT_FORMATS, n as downloadWorkflowExport, o as MAX_IMPORT_ARCHIVE_BYTES, p as importFileKind, r as parseWorkflowImport, s as MAX_IMPORT_SOURCE_BYTES, u as checkTypeScriptImport, v as primaryImportModule, w as workflowNameFromFile, x as typeScriptImportSource, y as readProjectArchive } from "./workflow-transfer-CktP7o1c.js";
|
|
14
14
|
import { i as canShareWorkflow, r as canEditWorkflow, t as WorkflowShareDialog } from "./WorkflowShareDialog-B9yZMhEi.js";
|
|
15
15
|
import { i as useOpenRequest, n as ACTION_PARAM_VALUES, r as useActionParam } from "./useActionParam-B0ebTZmg.js";
|
|
16
16
|
import { d as useFluidGridsFlag, t as FLUIDGRIDS_FLAGS } from "./feature-flags-B_b8PJ6Z.js";
|
|
17
|
-
import { n as downloadWorkflowExport, r as parseWorkflowImport } from "./workflow-transfer-CQnQC-ke.js";
|
|
18
17
|
import { a as useWorkflowProjects, i as useWorkflowProjectActions, n as useWorkflowFolderActions, r as useWorkflowFolders, t as useBulkWorkflowActions } from "./useWorkflowOrganization-r5FWNBs6.js";
|
|
19
18
|
import { t as describeOperationError } from "./errors-xPZ-IbQd.js";
|
|
20
19
|
import { a as useExecutions } from "./useExecutions-wka2Z5w3.js";
|
package/dist/executions.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { t as ExecutionsListPage } from "./ExecutionsListPage-
|
|
3
|
-
import { t as ExecutionDetailPage } from "./ExecutionDetailPage-
|
|
2
|
+
import { t as ExecutionsListPage } from "./ExecutionsListPage-CMrOaFKQ.js";
|
|
3
|
+
import { t as ExecutionDetailPage } from "./ExecutionDetailPage-DxeySgR3.js";
|
|
4
4
|
|
|
5
5
|
export { ExecutionDetailPage, ExecutionsListPage };
|