@revenexx/studio-integrations 0.1.3 → 0.2.0
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/module.json +1 -1
- package/dist/runtime/components/Integrations/CredentialCreateDialog.d.vue.ts +13 -0
- package/dist/runtime/components/Integrations/CredentialCreateDialog.vue +279 -0
- package/dist/runtime/components/Integrations/CredentialCreateDialog.vue.d.ts +13 -0
- package/dist/runtime/components/Integrations/CredentialDetailDialog.d.vue.ts +20 -0
- package/dist/runtime/components/Integrations/CredentialDetailDialog.vue +342 -0
- package/dist/runtime/components/Integrations/CredentialDetailDialog.vue.d.ts +20 -0
- package/dist/runtime/components/Integrations/CredentialLogo.d.vue.ts +14 -0
- package/dist/runtime/components/Integrations/CredentialLogo.vue +37 -0
- package/dist/runtime/components/Integrations/CredentialLogo.vue.d.ts +14 -0
- package/dist/runtime/components/Integrations/CredentialRevenexxSource.d.vue.ts +12 -0
- package/dist/runtime/components/Integrations/CredentialRevenexxSource.vue +364 -0
- package/dist/runtime/components/Integrations/CredentialRevenexxSource.vue.d.ts +12 -0
- package/dist/runtime/components/Integrations/CredentialTypePicker.d.vue.ts +15 -0
- package/dist/runtime/components/Integrations/CredentialTypePicker.vue +71 -0
- package/dist/runtime/components/Integrations/CredentialTypePicker.vue.d.ts +15 -0
- package/dist/runtime/components/Integrations/DeadLettersPanel.d.vue.ts +5 -0
- package/dist/runtime/components/Integrations/DeadLettersPanel.vue +151 -0
- package/dist/runtime/components/Integrations/DeadLettersPanel.vue.d.ts +5 -0
- package/dist/runtime/components/Integrations/EditorTip.d.vue.ts +17 -0
- package/dist/runtime/components/Integrations/EditorTip.vue +46 -0
- package/dist/runtime/components/Integrations/EditorTip.vue.d.ts +17 -0
- package/dist/runtime/components/Integrations/EventTypeCombobox.d.vue.ts +9 -0
- package/dist/runtime/components/Integrations/EventTypeCombobox.vue +64 -0
- package/dist/runtime/components/Integrations/EventTypeCombobox.vue.d.ts +9 -0
- package/dist/runtime/components/Integrations/ExpressionInput.d.vue.ts +19 -0
- package/dist/runtime/components/Integrations/ExpressionInput.vue +236 -0
- package/dist/runtime/components/Integrations/ExpressionInput.vue.d.ts +19 -0
- package/dist/runtime/components/Integrations/GroupFrameView.d.vue.ts +28 -0
- package/dist/runtime/components/Integrations/GroupFrameView.vue +222 -0
- package/dist/runtime/components/Integrations/GroupFrameView.vue.d.ts +28 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.d.vue.ts +14 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue +184 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue.d.ts +14 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.d.vue.ts +16 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.vue +102 -0
- package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.vue.d.ts +16 -0
- package/dist/runtime/components/Integrations/NodeConfigField.d.vue.ts +23 -0
- package/dist/runtime/components/Integrations/NodeConfigField.vue +587 -0
- package/dist/runtime/components/Integrations/NodeConfigField.vue.d.ts +23 -0
- package/dist/runtime/components/Integrations/NodeDynamicOutputsResolver.d.vue.ts +14 -0
- package/dist/runtime/components/Integrations/NodeDynamicOutputsResolver.vue +80 -0
- package/dist/runtime/components/Integrations/NodeDynamicOutputsResolver.vue.d.ts +14 -0
- package/dist/runtime/components/Integrations/NodeInspector.d.vue.ts +22 -3
- package/dist/runtime/components/Integrations/NodeInspector.vue +1074 -294
- package/dist/runtime/components/Integrations/NodeInspector.vue.d.ts +22 -3
- package/dist/runtime/components/Integrations/NodeLogo.d.vue.ts +9 -0
- package/dist/runtime/components/Integrations/NodeLogo.vue +38 -0
- package/dist/runtime/components/Integrations/NodeLogo.vue.d.ts +9 -0
- package/dist/runtime/components/Integrations/NodePalette.d.vue.ts +22 -1
- package/dist/runtime/components/Integrations/NodePalette.vue +411 -90
- package/dist/runtime/components/Integrations/NodePalette.vue.d.ts +22 -1
- package/dist/runtime/components/Integrations/QueryBuilder.d.vue.ts +9 -0
- package/dist/runtime/components/Integrations/QueryBuilder.vue +239 -0
- package/dist/runtime/components/Integrations/QueryBuilder.vue.d.ts +9 -0
- package/dist/runtime/components/Integrations/{RunDetailDialog.d.vue.ts → RunActionsMenu.d.vue.ts} +3 -4
- package/dist/runtime/components/Integrations/RunActionsMenu.vue +86 -0
- package/dist/runtime/components/Integrations/{RunDetailDialog.vue.d.ts → RunActionsMenu.vue.d.ts} +3 -4
- package/dist/runtime/components/Integrations/RunDetailPanel.d.vue.ts +14 -0
- package/dist/runtime/components/Integrations/RunDetailPanel.vue +777 -0
- package/dist/runtime/components/Integrations/RunDetailPanel.vue.d.ts +14 -0
- package/dist/runtime/components/Integrations/RunPayloadInput.d.vue.ts +13 -0
- package/dist/runtime/components/Integrations/RunPayloadInput.vue +175 -0
- package/dist/runtime/components/Integrations/RunPayloadInput.vue.d.ts +13 -0
- package/dist/runtime/components/Integrations/RunResponseModal.d.vue.ts +27 -0
- package/dist/runtime/components/Integrations/RunResponseModal.vue +84 -0
- package/dist/runtime/components/Integrations/RunResponseModal.vue.d.ts +27 -0
- package/dist/runtime/components/Integrations/RunsTable.d.vue.ts +21 -0
- package/dist/runtime/components/Integrations/RunsTable.vue +114 -0
- package/dist/runtime/components/Integrations/RunsTable.vue.d.ts +21 -0
- package/dist/runtime/components/Integrations/SftpAccountImportDialog.d.vue.ts +11 -0
- package/dist/runtime/components/Integrations/SftpAccountImportDialog.vue +91 -0
- package/dist/runtime/components/Integrations/SftpAccountImportDialog.vue.d.ts +11 -0
- package/dist/runtime/components/Integrations/Sidebar.vue +1 -0
- package/dist/runtime/components/Integrations/StickyNoteView.d.vue.ts +28 -0
- package/dist/runtime/components/Integrations/StickyNoteView.vue +208 -0
- package/dist/runtime/components/Integrations/StickyNoteView.vue.d.ts +28 -0
- package/dist/runtime/components/Integrations/TemplateFlowPreview.d.vue.ts +29 -0
- package/dist/runtime/components/Integrations/TemplateFlowPreview.vue +201 -0
- package/dist/runtime/components/Integrations/TemplateFlowPreview.vue.d.ts +29 -0
- package/dist/runtime/components/Integrations/WorkflowContextMenu.d.vue.ts +32 -0
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue +138 -0
- package/dist/runtime/components/Integrations/WorkflowContextMenu.vue.d.ts +32 -0
- package/dist/runtime/components/Integrations/WorkflowCreateDialog.d.vue.ts +9 -0
- package/dist/runtime/components/Integrations/WorkflowCreateDialog.vue +322 -0
- package/dist/runtime/components/Integrations/WorkflowCreateDialog.vue.d.ts +9 -0
- package/dist/runtime/components/Integrations/WorkflowDuplicateDialog.d.vue.ts +18 -0
- package/dist/runtime/components/Integrations/WorkflowDuplicateDialog.vue +63 -0
- package/dist/runtime/components/Integrations/WorkflowDuplicateDialog.vue.d.ts +18 -0
- package/dist/runtime/components/Integrations/WorkflowEdgeView.d.vue.ts +12 -1
- package/dist/runtime/components/Integrations/WorkflowEdgeView.vue +68 -6
- package/dist/runtime/components/Integrations/WorkflowEdgeView.vue.d.ts +12 -1
- package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +8 -1
- package/dist/runtime/components/Integrations/WorkflowEditor.vue +1424 -144
- package/dist/runtime/components/Integrations/WorkflowEditor.vue.d.ts +8 -1
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.d.vue.ts +12 -0
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue +417 -0
- package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue.d.ts +12 -0
- package/dist/runtime/components/Integrations/WorkflowIconPicker.d.vue.ts +10 -0
- package/dist/runtime/components/Integrations/WorkflowIconPicker.vue +89 -0
- package/dist/runtime/components/Integrations/WorkflowIconPicker.vue.d.ts +10 -0
- package/dist/runtime/components/Integrations/WorkflowIconView.d.vue.ts +10 -0
- package/dist/runtime/components/Integrations/WorkflowIconView.vue +35 -0
- package/dist/runtime/components/Integrations/WorkflowIconView.vue.d.ts +10 -0
- package/dist/runtime/components/Integrations/WorkflowNodeView.d.vue.ts +5 -1
- package/dist/runtime/components/Integrations/WorkflowNodeView.vue +114 -84
- package/dist/runtime/components/Integrations/WorkflowNodeView.vue.d.ts +5 -1
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.d.vue.ts +12 -0
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue +654 -0
- package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue.d.ts +12 -0
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.d.vue.ts +36 -0
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue +136 -0
- package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue.d.ts +36 -0
- package/dist/runtime/components/Integrations/WorkflowTagsInput.d.vue.ts +14 -0
- package/dist/runtime/components/Integrations/WorkflowTagsInput.vue +63 -0
- package/dist/runtime/components/Integrations/WorkflowTagsInput.vue.d.ts +14 -0
- package/dist/runtime/components/Integrations/WorkflowTriggerView.vue +35 -15
- package/dist/runtime/components/Integrations/WorkflowVariablesDialog.d.vue.ts +13 -0
- package/dist/runtime/components/Integrations/WorkflowVariablesDialog.vue +265 -0
- package/dist/runtime/components/Integrations/WorkflowVariablesDialog.vue.d.ts +13 -0
- package/dist/runtime/components/Integrations/WorkflowsTable.d.vue.ts +4 -1
- package/dist/runtime/components/Integrations/WorkflowsTable.vue +122 -39
- package/dist/runtime/components/Integrations/WorkflowsTable.vue.d.ts +4 -1
- package/dist/runtime/components/Integrations/workflowLayout.d.ts +5 -0
- package/dist/runtime/components/Integrations/workflowLayout.js +5 -3
- package/dist/runtime/composables/integrationsApi.d.ts +6 -2
- package/dist/runtime/composables/integrationsApi.js +5 -4
- package/dist/runtime/composables/useCanvasShortcuts.d.ts +37 -0
- package/dist/runtime/composables/useCanvasShortcuts.js +62 -0
- package/dist/runtime/composables/useIntegrationsDeadLetters.d.ts +22 -0
- package/dist/runtime/composables/useIntegrationsDeadLetters.js +50 -0
- package/dist/runtime/composables/useIntegrationsNodes.d.ts +4 -0
- package/dist/runtime/composables/useIntegrationsNodes.js +6 -3
- package/dist/runtime/composables/useIntegrationsRevisions.d.ts +40 -0
- package/dist/runtime/composables/useIntegrationsRevisions.js +51 -0
- package/dist/runtime/composables/useIntegrationsRuns.d.ts +21 -1
- package/dist/runtime/composables/useIntegrationsRuns.js +92 -4
- package/dist/runtime/composables/useIntegrationsTemplates.d.ts +1 -0
- package/dist/runtime/composables/useIntegrationsTemplates.js +32 -4
- package/dist/runtime/composables/useIntegrationsWorkflows.d.ts +1 -0
- package/dist/runtime/composables/useIntegrationsWorkflows.js +57 -1
- package/dist/runtime/composables/useMiniMapLayout.d.ts +34 -0
- package/dist/runtime/composables/useMiniMapLayout.js +119 -0
- package/dist/runtime/composables/useNodeConfigResolve.d.ts +43 -0
- package/dist/runtime/composables/useNodeConfigResolve.js +123 -0
- package/dist/runtime/composables/useNodeDrag.d.ts +22 -0
- package/dist/runtime/composables/useNodeDrag.js +10 -0
- package/dist/runtime/composables/usePaletteLayout.d.ts +41 -0
- package/dist/runtime/composables/usePaletteLayout.js +113 -0
- package/dist/runtime/data/expressionEditor.d.ts +22 -0
- package/dist/runtime/data/expressionEditor.js +40 -0
- package/dist/runtime/data/integrationNodeCatalog.js +8 -8
- package/dist/runtime/data/nodeInputData.d.ts +37 -0
- package/dist/runtime/data/nodeInputData.js +62 -0
- package/dist/runtime/data/nodeRunData.d.ts +56 -0
- package/dist/runtime/data/nodeRunData.js +91 -0
- package/dist/runtime/data/payloadForm.d.ts +44 -0
- package/dist/runtime/data/payloadForm.js +126 -0
- package/dist/runtime/data/workflowIconCatalog.d.ts +34 -0
- package/dist/runtime/data/workflowIconCatalog.js +116 -0
- package/dist/runtime/pages/integrations/audit.vue +25 -35
- package/dist/runtime/pages/integrations/credentials.vue +117 -122
- package/dist/runtime/pages/integrations/index.vue +133 -36
- package/dist/runtime/pages/integrations/runs.vue +125 -75
- package/dist/runtime/pages/integrations/schedules.vue +5 -16
- package/dist/runtime/pages/integrations/secrets.vue +1 -3
- package/dist/runtime/pages/integrations/workflows/[id].vue +599 -194
- package/dist/runtime/pages/integrations/workflows/index.vue +10 -8
- package/dist/runtime/types/integrations.d.ts +190 -4
- package/dist/runtime/utils/credentialState.d.ts +28 -0
- package/dist/runtime/utils/credentialState.js +29 -0
- package/dist/runtime/utils/localize.d.ts +3 -1
- package/dist/runtime/utils/localize.js +1 -2
- package/dist/runtime/utils/statusStyle.d.ts +6 -0
- package/dist/runtime/utils/statusStyle.js +15 -0
- package/package.json +12 -2
- package/dist/runtime/components/Integrations/RunDetailDialog.vue +0 -169
- package/dist/runtime/pages/integrations/workflows/new.d.vue.ts +0 -2
- package/dist/runtime/pages/integrations/workflows/new.vue +0 -153
- package/dist/runtime/pages/integrations/workflows/new.vue.d.ts +0 -2
|
@@ -0,0 +1,587 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, onMounted, ref, watch } from "vue";
|
|
3
|
+
import { AddCircle as Plus, TrashBinMinimalistic as Trash2 } from "#solar-icons";
|
|
4
|
+
import {
|
|
5
|
+
Button,
|
|
6
|
+
Input,
|
|
7
|
+
Label,
|
|
8
|
+
Select,
|
|
9
|
+
SelectContent,
|
|
10
|
+
SelectItem,
|
|
11
|
+
SelectTrigger,
|
|
12
|
+
SelectValue,
|
|
13
|
+
Switch,
|
|
14
|
+
Textarea
|
|
15
|
+
} from "@revenexx/studio";
|
|
16
|
+
const props = defineProps({
|
|
17
|
+
field: { type: Object, required: true },
|
|
18
|
+
config: { type: Object, required: true },
|
|
19
|
+
slug: { type: String, required: true },
|
|
20
|
+
version: { type: String, required: true },
|
|
21
|
+
secretKeys: { type: Array, required: true },
|
|
22
|
+
staticKeys: { type: Array, required: false },
|
|
23
|
+
depth: { type: Number, required: false },
|
|
24
|
+
variables: { type: Object, required: false },
|
|
25
|
+
upstreamOutputs: { type: Array, required: false }
|
|
26
|
+
});
|
|
27
|
+
const emit = defineEmits(["set"]);
|
|
28
|
+
const value = computed(() => props.config[props.field.key]);
|
|
29
|
+
function write(v) {
|
|
30
|
+
emit("set", props.field.key, v);
|
|
31
|
+
}
|
|
32
|
+
function labelText(v) {
|
|
33
|
+
if (!v) return "";
|
|
34
|
+
return typeof v === "string" ? v : v.en ?? Object.values(v)[0] ?? "";
|
|
35
|
+
}
|
|
36
|
+
const exprHint = "${{ \u2026 }}";
|
|
37
|
+
const descriptionText = computed(() => labelText(props.field.description));
|
|
38
|
+
function isEmpty(v) {
|
|
39
|
+
return v === void 0 || v === null || v === "" || Array.isArray(v) && v.length === 0;
|
|
40
|
+
}
|
|
41
|
+
const requiredMissing = computed(() => !!props.field.required && isEmpty(value.value));
|
|
42
|
+
const formatError = computed(() => {
|
|
43
|
+
const v = value.value;
|
|
44
|
+
if (isEmpty(v)) return null;
|
|
45
|
+
const val = props.field.validation;
|
|
46
|
+
if (!val) return null;
|
|
47
|
+
if (typeof v === "string") {
|
|
48
|
+
if (val.minLength != null && v.length < val.minLength) return `Must be at least ${val.minLength} characters`;
|
|
49
|
+
if (val.maxLength != null && v.length > val.maxLength) return `Must be at most ${val.maxLength} characters`;
|
|
50
|
+
if (val.pattern) {
|
|
51
|
+
try {
|
|
52
|
+
if (!new RegExp(val.pattern).test(v)) return "Does not match the required format";
|
|
53
|
+
} catch {
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (typeof v === "number") {
|
|
58
|
+
if (val.min != null && v < val.min) return `Must be \u2265 ${val.min}`;
|
|
59
|
+
if (val.max != null && v > val.max) return `Must be \u2264 ${val.max}`;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
});
|
|
63
|
+
const invalid = computed(() => !!formatError.value);
|
|
64
|
+
const constraintHint = computed(() => {
|
|
65
|
+
const val = props.field.validation;
|
|
66
|
+
if (!val) return "";
|
|
67
|
+
if (props.field.type === "number") {
|
|
68
|
+
if (val.min != null && val.max != null) return `${val.min}\u2013${val.max}`;
|
|
69
|
+
if (val.min != null) return `\u2265 ${val.min}`;
|
|
70
|
+
if (val.max != null) return `\u2264 ${val.max}`;
|
|
71
|
+
} else {
|
|
72
|
+
if (val.minLength != null && val.maxLength != null) return `${val.minLength}\u2013${val.maxLength} characters`;
|
|
73
|
+
if (val.minLength != null) return `at least ${val.minLength} characters`;
|
|
74
|
+
if (val.maxLength != null) return `up to ${val.maxLength} characters`;
|
|
75
|
+
}
|
|
76
|
+
return "";
|
|
77
|
+
});
|
|
78
|
+
const { credentials, load: loadCredentials } = useIntegrationsCredentials();
|
|
79
|
+
onMounted(() => {
|
|
80
|
+
void loadCredentials();
|
|
81
|
+
});
|
|
82
|
+
function credsOfType(slug) {
|
|
83
|
+
if (!slug) return credentials.value;
|
|
84
|
+
const slugs = (Array.isArray(slug) ? slug : [slug]).map((s) => s.trim()).filter(Boolean);
|
|
85
|
+
if (!slugs.length) return credentials.value;
|
|
86
|
+
const wanted = new Set(slugs);
|
|
87
|
+
return credentials.value.filter((c) => wanted.has(c.credential_type_slug));
|
|
88
|
+
}
|
|
89
|
+
function credsForField(field) {
|
|
90
|
+
const list = credsOfType(field.credentialType);
|
|
91
|
+
const selectedId = value.value;
|
|
92
|
+
if (selectedId && !list.some((c) => c.id === selectedId)) {
|
|
93
|
+
const sel = credentials.value.find((c) => c.id === selectedId);
|
|
94
|
+
if (sel) return [sel, ...list];
|
|
95
|
+
}
|
|
96
|
+
return list;
|
|
97
|
+
}
|
|
98
|
+
function credNeedsReauth(id) {
|
|
99
|
+
return credentials.value.some((c) => c.id === id && c.status === "needs_reauth");
|
|
100
|
+
}
|
|
101
|
+
const credCreateOpen = ref(false);
|
|
102
|
+
const sftpImportOpen = ref(false);
|
|
103
|
+
function acceptsSftp(field) {
|
|
104
|
+
const t = field.credentialType;
|
|
105
|
+
return t === "revenexx:sftp" || Array.isArray(t) && t.includes("revenexx:sftp");
|
|
106
|
+
}
|
|
107
|
+
const EXPR_TOKEN = "${{";
|
|
108
|
+
const canToggleExpression = computed(
|
|
109
|
+
() => !!props.field.dynamic || ["number", "boolean", "select", "multiselect"].includes(props.field.type)
|
|
110
|
+
);
|
|
111
|
+
const exprMode = ref(false);
|
|
112
|
+
const valueIsExpression = computed(() => typeof value.value === "string" && value.value.includes(EXPR_TOKEN));
|
|
113
|
+
const showExpression = computed(() => canToggleExpression.value && (exprMode.value || valueIsExpression.value));
|
|
114
|
+
function toggleExpression() {
|
|
115
|
+
if (showExpression.value) {
|
|
116
|
+
if (valueIsExpression.value) write(void 0);
|
|
117
|
+
exprMode.value = false;
|
|
118
|
+
} else {
|
|
119
|
+
exprMode.value = true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
const isObjectField = computed(() => props.field.type === "object");
|
|
123
|
+
function isFlatObject(v) {
|
|
124
|
+
return !!v && typeof v === "object" && !Array.isArray(v) && Object.values(v).every((x) => x === null || ["string", "number", "boolean"].includes(typeof x));
|
|
125
|
+
}
|
|
126
|
+
const flatCapable = computed(() => {
|
|
127
|
+
const v = value.value;
|
|
128
|
+
return v === void 0 || v === null || isFlatObject(v);
|
|
129
|
+
});
|
|
130
|
+
const objectMode = ref("form");
|
|
131
|
+
watch(flatCapable, (flat) => {
|
|
132
|
+
if (!flat) objectMode.value = "json";
|
|
133
|
+
}, { immediate: true });
|
|
134
|
+
const kvRows = ref([]);
|
|
135
|
+
function rowsToObject(rows) {
|
|
136
|
+
const out = {};
|
|
137
|
+
for (const r of rows) {
|
|
138
|
+
if (r.key.trim() !== "") out[r.key.trim()] = r.value;
|
|
139
|
+
}
|
|
140
|
+
return out;
|
|
141
|
+
}
|
|
142
|
+
watch(
|
|
143
|
+
() => props.config[props.field.key],
|
|
144
|
+
(v) => {
|
|
145
|
+
if (!isObjectField.value) return;
|
|
146
|
+
const external = v && typeof v === "object" && !Array.isArray(v) ? v : {};
|
|
147
|
+
if (JSON.stringify(rowsToObject(kvRows.value)) !== JSON.stringify(external)) {
|
|
148
|
+
kvRows.value = Object.entries(external).map(([k, val]) => ({
|
|
149
|
+
key: k,
|
|
150
|
+
value: typeof val === "string" ? val : JSON.stringify(val)
|
|
151
|
+
}));
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
{ immediate: true }
|
|
155
|
+
);
|
|
156
|
+
function commitKvRows() {
|
|
157
|
+
const obj = rowsToObject(kvRows.value);
|
|
158
|
+
write(Object.keys(obj).length || kvRows.value.length ? obj : void 0);
|
|
159
|
+
}
|
|
160
|
+
function setKvRow(idx, patch) {
|
|
161
|
+
kvRows.value = kvRows.value.map((r, i) => i === idx ? { ...r, ...patch } : r);
|
|
162
|
+
commitKvRows();
|
|
163
|
+
}
|
|
164
|
+
function addKvRow() {
|
|
165
|
+
kvRows.value = [...kvRows.value, { key: "", value: "" }];
|
|
166
|
+
}
|
|
167
|
+
function removeKvRow(idx) {
|
|
168
|
+
kvRows.value = kvRows.value.filter((_, i) => i !== idx);
|
|
169
|
+
commitKvRows();
|
|
170
|
+
}
|
|
171
|
+
const isQueryField = computed(
|
|
172
|
+
() => props.field.type === "array" && props.field.items?.type !== "object" && /(^|__)queries$/.test(props.field.key)
|
|
173
|
+
);
|
|
174
|
+
const isJsonField = computed(
|
|
175
|
+
() => isObjectField.value && objectMode.value === "json" || props.field.type === "array" && props.field.items?.type !== "object" && !isQueryField.value
|
|
176
|
+
);
|
|
177
|
+
const jsonError = ref(null);
|
|
178
|
+
const jsonDraft = ref("");
|
|
179
|
+
watch(
|
|
180
|
+
() => [props.config[props.field.key], isJsonField.value],
|
|
181
|
+
([v]) => {
|
|
182
|
+
if (!isJsonField.value) return;
|
|
183
|
+
const current = (() => {
|
|
184
|
+
try {
|
|
185
|
+
return JSON.parse(jsonDraft.value);
|
|
186
|
+
} catch {
|
|
187
|
+
return /* @__PURE__ */ Symbol("invalid");
|
|
188
|
+
}
|
|
189
|
+
})();
|
|
190
|
+
if (JSON.stringify(current) !== JSON.stringify(v)) {
|
|
191
|
+
jsonDraft.value = v === void 0 || v === null ? "" : JSON.stringify(v, null, 2);
|
|
192
|
+
jsonError.value = null;
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
{ immediate: true }
|
|
196
|
+
);
|
|
197
|
+
function writeJson(text) {
|
|
198
|
+
jsonDraft.value = text;
|
|
199
|
+
if (text.trim() === "") {
|
|
200
|
+
jsonError.value = null;
|
|
201
|
+
emit("set", props.field.key, void 0);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
const parsed = JSON.parse(text);
|
|
206
|
+
jsonError.value = null;
|
|
207
|
+
emit("set", props.field.key, parsed);
|
|
208
|
+
} catch {
|
|
209
|
+
jsonError.value = "Not valid JSON yet \u2014 the value is kept once it parses.";
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
function readArray() {
|
|
213
|
+
return Array.isArray(value.value) ? value.value : [];
|
|
214
|
+
}
|
|
215
|
+
function pushArrayItem(defaultItem) {
|
|
216
|
+
write([...readArray(), defaultItem]);
|
|
217
|
+
}
|
|
218
|
+
function removeArrayItem(index) {
|
|
219
|
+
const arr = readArray().slice();
|
|
220
|
+
arr.splice(index, 1);
|
|
221
|
+
write(arr);
|
|
222
|
+
}
|
|
223
|
+
function setArrayItemField(index, fieldKey, v) {
|
|
224
|
+
const arr = readArray().slice();
|
|
225
|
+
arr[index] = { ...arr[index] ?? {}, [fieldKey]: v };
|
|
226
|
+
write(arr);
|
|
227
|
+
}
|
|
228
|
+
</script>
|
|
229
|
+
|
|
230
|
+
<template>
|
|
231
|
+
<div class="space-y-1.5">
|
|
232
|
+
<div class="flex items-center justify-between gap-2">
|
|
233
|
+
<Label class="text-mono text-muted-foreground">
|
|
234
|
+
{{ labelText(field.label) }}<span v-if="field.required" class="text-rose-500" title="Required"> *</span>
|
|
235
|
+
</Label>
|
|
236
|
+
<div class="flex shrink-0 items-center gap-1.5">
|
|
237
|
+
<div v-if="isObjectField && !showExpression" class="flex items-center rounded border border-black/[0.08] bg-white p-px">
|
|
238
|
+
<button
|
|
239
|
+
type="button"
|
|
240
|
+
:disabled="!flatCapable"
|
|
241
|
+
title="Edit as key/value rows"
|
|
242
|
+
class="rounded px-1 py-px text-[10px] font-medium transition disabled:pointer-events-none disabled:opacity-40"
|
|
243
|
+
:class="objectMode === 'form' ? 'bg-slate-100 text-foreground' : 'text-muted-foreground hover:text-foreground'"
|
|
244
|
+
@click="objectMode = 'form'"
|
|
245
|
+
>
|
|
246
|
+
Fields
|
|
247
|
+
</button>
|
|
248
|
+
<button
|
|
249
|
+
type="button"
|
|
250
|
+
title="Edit as raw JSON"
|
|
251
|
+
class="rounded px-1 py-px text-[10px] font-medium transition"
|
|
252
|
+
:class="objectMode === 'json' ? 'bg-slate-100 text-foreground' : 'text-muted-foreground hover:text-foreground'"
|
|
253
|
+
@click="objectMode = 'json'"
|
|
254
|
+
>
|
|
255
|
+
JSON
|
|
256
|
+
</button>
|
|
257
|
+
</div>
|
|
258
|
+
<button
|
|
259
|
+
v-if="canToggleExpression"
|
|
260
|
+
type="button"
|
|
261
|
+
class="rounded border px-1 py-0.5 font-mono text-[10px] transition"
|
|
262
|
+
:class="showExpression ? 'border-emerald-500/40 bg-emerald-500/15 text-emerald-700' : 'border-black/[0.08] bg-white text-muted-foreground hover:text-foreground'"
|
|
263
|
+
:title="showExpression ? 'Back to the regular control (clears the expression)' : 'Map this value from a previous step instead'"
|
|
264
|
+
@click="toggleExpression"
|
|
265
|
+
>
|
|
266
|
+
{{ exprHint }}
|
|
267
|
+
</button>
|
|
268
|
+
<span
|
|
269
|
+
v-else-if="field.expressionAllowed"
|
|
270
|
+
class="rounded border border-emerald-500/25 bg-emerald-500/10 px-1 py-0.5 font-mono text-[10px] text-emerald-600"
|
|
271
|
+
title="Accepts ${{ … }} expressions"
|
|
272
|
+
>
|
|
273
|
+
{{ exprHint }}
|
|
274
|
+
</span>
|
|
275
|
+
</div>
|
|
276
|
+
</div>
|
|
277
|
+
<!-- inline help (boolean uses its description as the toggle label instead) -->
|
|
278
|
+
<p v-if="descriptionText && field.type !== 'boolean'" class="text-sm text-muted-foreground leading-snug">
|
|
279
|
+
{{ descriptionText }}
|
|
280
|
+
</p>
|
|
281
|
+
|
|
282
|
+
<!-- object / plain-array fields: JSON editor (expressions stay usable
|
|
283
|
+
inside string values). Wins over expressionAllowed — an object value
|
|
284
|
+
in a text input would render as [object Object]. -->
|
|
285
|
+
<!-- queries parameter: filter builder -->
|
|
286
|
+
<IntegrationsQueryBuilder
|
|
287
|
+
v-if="isQueryField"
|
|
288
|
+
:model-value="value"
|
|
289
|
+
@update:model-value="(v) => write(v)"
|
|
290
|
+
/>
|
|
291
|
+
|
|
292
|
+
<template v-else-if="isJsonField">
|
|
293
|
+
<Textarea
|
|
294
|
+
:model-value="jsonDraft"
|
|
295
|
+
:rows="8"
|
|
296
|
+
spellcheck="false"
|
|
297
|
+
class="font-mono text-xs"
|
|
298
|
+
:placeholder="labelText(field.placeholder) || '{ }'"
|
|
299
|
+
@update:model-value="(v) => writeJson(String(v))"
|
|
300
|
+
/>
|
|
301
|
+
<p v-if="jsonError" class="text-sm text-amber-600">{{ jsonError }}</p>
|
|
302
|
+
</template>
|
|
303
|
+
|
|
304
|
+
<!-- object field in key/value mode -->
|
|
305
|
+
<div v-else-if="isObjectField && objectMode === 'form'" class="space-y-1.5">
|
|
306
|
+
<div v-for="(row, idx) in kvRows" :key="idx" class="flex items-center gap-1.5">
|
|
307
|
+
<Input
|
|
308
|
+
:model-value="row.key"
|
|
309
|
+
placeholder="key"
|
|
310
|
+
class="h-7 w-[38%] bg-white font-mono text-sm"
|
|
311
|
+
@update:model-value="(v) => setKvRow(idx, { key: String(v) })"
|
|
312
|
+
/>
|
|
313
|
+
<Input
|
|
314
|
+
:model-value="row.value"
|
|
315
|
+
placeholder="value"
|
|
316
|
+
class="h-7 min-w-0 flex-1 bg-white text-sm"
|
|
317
|
+
@update:model-value="(v) => setKvRow(idx, { value: String(v) })"
|
|
318
|
+
/>
|
|
319
|
+
<button
|
|
320
|
+
type="button"
|
|
321
|
+
class="flex size-6 shrink-0 items-center justify-center rounded text-muted-foreground transition hover:text-rose-600"
|
|
322
|
+
@click="removeKvRow(idx)"
|
|
323
|
+
>
|
|
324
|
+
<Trash2 :size="11" />
|
|
325
|
+
</button>
|
|
326
|
+
</div>
|
|
327
|
+
<Button
|
|
328
|
+
type="button"
|
|
329
|
+
variant="outline"
|
|
330
|
+
size="sm"
|
|
331
|
+
class="h-7 w-full text-sm"
|
|
332
|
+
@click="addKvRow"
|
|
333
|
+
>
|
|
334
|
+
<Plus :size="11" />
|
|
335
|
+
Add row
|
|
336
|
+
</Button>
|
|
337
|
+
</div>
|
|
338
|
+
|
|
339
|
+
<!-- typed control flipped to expression mode -->
|
|
340
|
+
<IntegrationsExpressionInput
|
|
341
|
+
v-else-if="showExpression"
|
|
342
|
+
:model-value="typeof value === 'string' ? value : ''"
|
|
343
|
+
:placeholder="labelText(field.placeholder)"
|
|
344
|
+
:variables="variables"
|
|
345
|
+
:upstream-outputs="upstreamOutputs"
|
|
346
|
+
@update:model-value="(v) => write(v)"
|
|
347
|
+
/>
|
|
348
|
+
|
|
349
|
+
<!-- dynamic options — resolved at author time via config:resolve. Ahead of
|
|
350
|
+
the generic expression branch so a dynamic select with
|
|
351
|
+
expressionAllowed still renders as a dropdown by default. -->
|
|
352
|
+
<IntegrationsNodeConfigDynamicField
|
|
353
|
+
v-else-if="field.dynamic"
|
|
354
|
+
:slug="slug"
|
|
355
|
+
:version="version"
|
|
356
|
+
:field="field"
|
|
357
|
+
:config="config"
|
|
358
|
+
:model-value="value"
|
|
359
|
+
@update:model-value="write"
|
|
360
|
+
/>
|
|
361
|
+
|
|
362
|
+
<!-- expression-capable string: token-autocomplete input -->
|
|
363
|
+
<IntegrationsExpressionInput
|
|
364
|
+
v-else-if="field.type === 'expression' || field.expressionAllowed"
|
|
365
|
+
:model-value="value"
|
|
366
|
+
:placeholder="labelText(field.placeholder)"
|
|
367
|
+
:variables="variables"
|
|
368
|
+
:upstream-outputs="upstreamOutputs"
|
|
369
|
+
@update:model-value="(v) => write(v)"
|
|
370
|
+
/>
|
|
371
|
+
|
|
372
|
+
<!-- plain string (no expressions) -->
|
|
373
|
+
<Input
|
|
374
|
+
v-else-if="field.type === 'string'"
|
|
375
|
+
:model-value="value ?? ''"
|
|
376
|
+
:placeholder="labelText(field.placeholder)"
|
|
377
|
+
class="h-8 text-sm bg-white"
|
|
378
|
+
:class="invalid ? 'border-rose-400 focus-visible:ring-rose-400/40' : ''"
|
|
379
|
+
@update:model-value="(v) => write(v)"
|
|
380
|
+
/>
|
|
381
|
+
|
|
382
|
+
<!-- number -->
|
|
383
|
+
<Input
|
|
384
|
+
v-else-if="field.type === 'number'"
|
|
385
|
+
type="number"
|
|
386
|
+
:model-value="value ?? ''"
|
|
387
|
+
class="h-8 text-sm bg-white"
|
|
388
|
+
:class="invalid ? 'border-rose-400 focus-visible:ring-rose-400/40' : ''"
|
|
389
|
+
@update:model-value="(v) => write(v === '' ? null : Number(v))"
|
|
390
|
+
/>
|
|
391
|
+
|
|
392
|
+
<!-- boolean -->
|
|
393
|
+
<div v-else-if="field.type === 'boolean'" class="flex items-center gap-2 pt-1">
|
|
394
|
+
<Switch
|
|
395
|
+
:model-value="Boolean(value)"
|
|
396
|
+
@update:model-value="(v) => write(v)"
|
|
397
|
+
/>
|
|
398
|
+
<span class="text-sm text-muted-foreground">
|
|
399
|
+
{{ labelText(field.description) }}
|
|
400
|
+
</span>
|
|
401
|
+
</div>
|
|
402
|
+
|
|
403
|
+
<!-- dynamic schema — child fields resolved at author time, written into the flat config -->
|
|
404
|
+
<IntegrationsNodeConfigDynamicSchema
|
|
405
|
+
v-else-if="field.type === 'dynamic-schema'"
|
|
406
|
+
:slug="slug"
|
|
407
|
+
:version="version"
|
|
408
|
+
:field="field"
|
|
409
|
+
:config="config"
|
|
410
|
+
:static-keys="staticKeys ?? []"
|
|
411
|
+
:secret-keys="secretKeys"
|
|
412
|
+
:depth="depth ?? 0"
|
|
413
|
+
@set="(k, v) => emit('set', k, v)"
|
|
414
|
+
/>
|
|
415
|
+
|
|
416
|
+
<!-- select -->
|
|
417
|
+
<Select
|
|
418
|
+
v-else-if="field.type === 'select'"
|
|
419
|
+
:model-value="value ?? ''"
|
|
420
|
+
@update:model-value="(v) => write(v)"
|
|
421
|
+
>
|
|
422
|
+
<SelectTrigger class="h-8 text-sm bg-white">
|
|
423
|
+
<SelectValue :placeholder="labelText(field.placeholder) || 'Pick one'" />
|
|
424
|
+
</SelectTrigger>
|
|
425
|
+
<SelectContent>
|
|
426
|
+
<SelectItem v-for="opt in field.options ?? []" :key="String(opt.value)" :value="String(opt.value)">
|
|
427
|
+
{{ labelText(opt.label) }}
|
|
428
|
+
</SelectItem>
|
|
429
|
+
</SelectContent>
|
|
430
|
+
</Select>
|
|
431
|
+
|
|
432
|
+
<!-- multiselect — pill toggles for now -->
|
|
433
|
+
<div v-else-if="field.type === 'multiselect'" class="flex flex-wrap gap-1">
|
|
434
|
+
<button
|
|
435
|
+
v-for="opt in field.options ?? []"
|
|
436
|
+
:key="String(opt.value)"
|
|
437
|
+
type="button"
|
|
438
|
+
class="rounded-md border border-black/[0.08] px-1.5 py-0.5 text-sm transition"
|
|
439
|
+
:class="(value ?? []).includes(opt.value) ? 'bg-emerald-500/15 text-emerald-700 border-emerald-500/30' : 'bg-white text-muted-foreground hover:text-foreground'"
|
|
440
|
+
@click="() => {
|
|
441
|
+
const current = value ?? [];
|
|
442
|
+
const has = current.includes(opt.value);
|
|
443
|
+
write(has ? current.filter((v) => v !== opt.value) : [...current, opt.value]);
|
|
444
|
+
}"
|
|
445
|
+
>
|
|
446
|
+
{{ labelText(opt.label) }}
|
|
447
|
+
</button>
|
|
448
|
+
</div>
|
|
449
|
+
|
|
450
|
+
<!-- secret-ref -->
|
|
451
|
+
<Select
|
|
452
|
+
v-else-if="field.type === 'secret-ref'"
|
|
453
|
+
:model-value="value ?? ''"
|
|
454
|
+
@update:model-value="(v) => write(v)"
|
|
455
|
+
>
|
|
456
|
+
<SelectTrigger class="h-8 text-sm bg-white">
|
|
457
|
+
<SelectValue placeholder="Pick a secret" />
|
|
458
|
+
</SelectTrigger>
|
|
459
|
+
<SelectContent>
|
|
460
|
+
<SelectItem v-for="k in secretKeys" :key="k" :value="k">{{ k }}</SelectItem>
|
|
461
|
+
</SelectContent>
|
|
462
|
+
</Select>
|
|
463
|
+
|
|
464
|
+
<!-- credentials-ref — pick a credential of the required type -->
|
|
465
|
+
<template v-else-if="field.type === 'credentials-ref'">
|
|
466
|
+
<Select
|
|
467
|
+
:model-value="value ?? ''"
|
|
468
|
+
@update:model-value="(v) => write(v)"
|
|
469
|
+
>
|
|
470
|
+
<SelectTrigger class="h-8 text-sm bg-white">
|
|
471
|
+
<SelectValue placeholder="Pick a credential" />
|
|
472
|
+
</SelectTrigger>
|
|
473
|
+
<SelectContent>
|
|
474
|
+
<SelectItem v-for="c in credsForField(field)" :key="c.id" :value="c.id">
|
|
475
|
+
<span class="flex items-center gap-1.5">
|
|
476
|
+
<span class="size-1.5 shrink-0 rounded-full" :class="c.status === 'needs_reauth' ? 'bg-amber-500' : 'bg-emerald-500'" />
|
|
477
|
+
<span class="min-w-0 truncate">{{ c.name }}</span>
|
|
478
|
+
<span v-if="c.status === 'needs_reauth'" class="shrink-0 text-[10px] text-amber-600">reconnect</span>
|
|
479
|
+
</span>
|
|
480
|
+
</SelectItem>
|
|
481
|
+
</SelectContent>
|
|
482
|
+
</Select>
|
|
483
|
+
<p v-if="credNeedsReauth(value)" class="text-sm text-amber-600">
|
|
484
|
+
This credential needs reconnect.
|
|
485
|
+
</p>
|
|
486
|
+
<div class="flex items-center gap-3">
|
|
487
|
+
<button type="button" class="text-sm font-medium text-violet-600 hover:underline" @click="credCreateOpen = true">
|
|
488
|
+
+ New credential
|
|
489
|
+
</button>
|
|
490
|
+
<button
|
|
491
|
+
v-if="acceptsSftp(field)"
|
|
492
|
+
type="button"
|
|
493
|
+
class="text-sm font-medium text-violet-600 hover:underline"
|
|
494
|
+
@click="sftpImportOpen = true"
|
|
495
|
+
>
|
|
496
|
+
Import SFTP account
|
|
497
|
+
</button>
|
|
498
|
+
<NuxtLink to="/integrations/credentials" class="text-sm text-muted-foreground hover:underline">
|
|
499
|
+
Manage →
|
|
500
|
+
</NuxtLink>
|
|
501
|
+
</div>
|
|
502
|
+
<IntegrationsCredentialCreateDialog
|
|
503
|
+
v-model:open="credCreateOpen"
|
|
504
|
+
:credential-type="field.credentialType"
|
|
505
|
+
@created="(id) => write(id)"
|
|
506
|
+
/>
|
|
507
|
+
<IntegrationsSftpAccountImportDialog
|
|
508
|
+
v-if="acceptsSftp(field)"
|
|
509
|
+
v-model:open="sftpImportOpen"
|
|
510
|
+
@created="(id) => write(id)"
|
|
511
|
+
/>
|
|
512
|
+
</template>
|
|
513
|
+
|
|
514
|
+
<!-- array of objects (e.g. headers / mappings) -->
|
|
515
|
+
<div v-else-if="field.type === 'array' && field.items?.type === 'object'" class="space-y-2">
|
|
516
|
+
<div
|
|
517
|
+
v-for="(item, idx) in readArray()"
|
|
518
|
+
:key="idx"
|
|
519
|
+
class="rounded-md border border-black/[0.06] bg-muted/20 p-2 space-y-1.5"
|
|
520
|
+
>
|
|
521
|
+
<div class="flex items-center justify-between">
|
|
522
|
+
<span class="text-mono text-muted-foreground">
|
|
523
|
+
#{{ idx + 1 }}
|
|
524
|
+
</span>
|
|
525
|
+
<button
|
|
526
|
+
type="button"
|
|
527
|
+
class="flex size-5 items-center justify-center rounded text-muted-foreground hover:text-rose-600"
|
|
528
|
+
@click="removeArrayItem(idx)"
|
|
529
|
+
>
|
|
530
|
+
<Trash2 :size="11" />
|
|
531
|
+
</button>
|
|
532
|
+
</div>
|
|
533
|
+
<div
|
|
534
|
+
v-for="sub in field.items.properties ?? []"
|
|
535
|
+
:key="sub.key"
|
|
536
|
+
class="space-y-1"
|
|
537
|
+
>
|
|
538
|
+
<Label class="text-mono text-muted-foreground">
|
|
539
|
+
{{ labelText(sub.label) }}
|
|
540
|
+
</Label>
|
|
541
|
+
<Input
|
|
542
|
+
:model-value="item[sub.key] ?? ''"
|
|
543
|
+
:placeholder="labelText(sub.placeholder)"
|
|
544
|
+
class="h-7 text-sm bg-white"
|
|
545
|
+
:class="sub.type === 'expression' ? 'font-mono' : ''"
|
|
546
|
+
@update:model-value="(v) => setArrayItemField(idx, sub.key, v)"
|
|
547
|
+
/>
|
|
548
|
+
</div>
|
|
549
|
+
</div>
|
|
550
|
+
<Button
|
|
551
|
+
type="button"
|
|
552
|
+
variant="outline"
|
|
553
|
+
size="sm"
|
|
554
|
+
class="h-7 text-sm w-full"
|
|
555
|
+
@click="pushArrayItem(Object.fromEntries((field.items?.properties ?? []).map((p) => [p.key, ''])))"
|
|
556
|
+
>
|
|
557
|
+
<Plus :size="11" />
|
|
558
|
+
Add row
|
|
559
|
+
</Button>
|
|
560
|
+
</div>
|
|
561
|
+
|
|
562
|
+
<!-- fallback: JSON textarea for complex types -->
|
|
563
|
+
<Textarea
|
|
564
|
+
v-else
|
|
565
|
+
:model-value="value === void 0 ? '' : JSON.stringify(value, null, 2)"
|
|
566
|
+
rows="3"
|
|
567
|
+
class="text-sm font-mono bg-white"
|
|
568
|
+
@update:model-value="(v) => {
|
|
569
|
+
try {
|
|
570
|
+
write(v ? JSON.parse(String(v)) : void 0);
|
|
571
|
+
} catch {
|
|
572
|
+
}
|
|
573
|
+
}"
|
|
574
|
+
/>
|
|
575
|
+
|
|
576
|
+
<!-- validation feedback: hard error, else soft required hint, else constraint hint -->
|
|
577
|
+
<p v-if="formatError" class="text-sm text-rose-600">
|
|
578
|
+
{{ formatError }}
|
|
579
|
+
</p>
|
|
580
|
+
<p v-else-if="requiredMissing" class="text-sm text-amber-600">
|
|
581
|
+
Required
|
|
582
|
+
</p>
|
|
583
|
+
<p v-else-if="constraintHint" class="text-sm text-muted-foreground">
|
|
584
|
+
{{ constraintHint }}
|
|
585
|
+
</p>
|
|
586
|
+
</div>
|
|
587
|
+
</template>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ConfigField, WorkflowVariable } from '../../types/integrations.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
field: ConfigField;
|
|
4
|
+
config: Record<string, unknown>;
|
|
5
|
+
slug: string;
|
|
6
|
+
version: string;
|
|
7
|
+
secretKeys: string[];
|
|
8
|
+
staticKeys?: string[];
|
|
9
|
+
depth?: number;
|
|
10
|
+
variables?: Record<string, WorkflowVariable>;
|
|
11
|
+
upstreamOutputs?: Array<{
|
|
12
|
+
nodeId: string;
|
|
13
|
+
nodeName?: string;
|
|
14
|
+
output: string;
|
|
15
|
+
fields?: string[];
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
19
|
+
set: (key: string, value: unknown) => any;
|
|
20
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
21
|
+
onSet?: ((key: string, value: unknown) => any) | undefined;
|
|
22
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
23
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { NodeManifestOutput } from '../../types/integrations.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
nodeId: string;
|
|
4
|
+
slug: string;
|
|
5
|
+
version: string;
|
|
6
|
+
config: Record<string, unknown>;
|
|
7
|
+
staticOutputs: NodeManifestOutput[];
|
|
8
|
+
};
|
|
9
|
+
declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
10
|
+
resolved: (nodeId: string, outputs: NodeManifestOutput[]) => any;
|
|
11
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
12
|
+
onResolved?: ((nodeId: string, outputs: NodeManifestOutput[]) => any) | undefined;
|
|
13
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
export default _default;
|