@flowdrop/flowdrop 1.6.0 → 1.7.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/components/App.svelte +62 -31
- package/dist/components/App.svelte.d.ts +3 -1
- package/dist/components/form/FormCodeEditor.svelte +4 -3
- package/dist/components/nodes/SimpleNode.svelte +8 -8
- package/dist/schemas/v1/workflow.schema.json +5 -0
- package/dist/stores/workflowStore.svelte.d.ts +1 -0
- package/dist/stores/workflowStore.svelte.js +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/utils/connections.d.ts +4 -0
- package/dist/utils/connections.js +6 -0
- package/package.json +1 -1
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
import { getUiSettings, updateSettings } from '../stores/settingsStore.svelte.js';
|
|
58
58
|
import {
|
|
59
59
|
initializePortCompatibility,
|
|
60
|
-
getPortCompatibilityChecker
|
|
60
|
+
getPortCompatibilityChecker,
|
|
61
|
+
isPortCompatibilityInitialized
|
|
61
62
|
} from '../utils/connections.js';
|
|
62
63
|
import { DEFAULT_PORT_CONFIG } from '../config/defaultPortConfig.js';
|
|
63
64
|
import { workflowFormatRegistry } from '../registry/workflowFormatRegistry.js';
|
|
@@ -121,6 +122,8 @@
|
|
|
121
122
|
showSettingsResetButton?: boolean;
|
|
122
123
|
/** Pluggable swap strategies — instance-scoped, checked in order */
|
|
123
124
|
swapStrategies?: SwapStrategy[];
|
|
125
|
+
/** Additional JSON Schema properties to show in the Workflow Settings panel. Values are persisted in workflow.config. */
|
|
126
|
+
workflowSettingsSchema?: ConfigSchema;
|
|
124
127
|
}
|
|
125
128
|
|
|
126
129
|
let {
|
|
@@ -146,7 +149,8 @@
|
|
|
146
149
|
settingsCategories,
|
|
147
150
|
showSettingsSyncButton,
|
|
148
151
|
showSettingsResetButton,
|
|
149
|
-
swapStrategies
|
|
152
|
+
swapStrategies,
|
|
153
|
+
workflowSettingsSchema
|
|
150
154
|
}: Props = $props();
|
|
151
155
|
|
|
152
156
|
// svelte-ignore state_referenced_locally — feature flags don't change at runtime
|
|
@@ -223,39 +227,60 @@
|
|
|
223
227
|
let swapTargetMetadata = $state<NodeMetadata | null>(null);
|
|
224
228
|
let swapInteractiveState = $state<InteractiveSwapState | null>(null);
|
|
225
229
|
|
|
230
|
+
// Built-in workflow settings field names — consumer schemas must not reuse these.
|
|
231
|
+
const WORKFLOW_SETTINGS_RESERVED = new Set(['name', 'description', 'format']);
|
|
232
|
+
|
|
226
233
|
// Workflow configuration schema (derived to pick up dynamic format options)
|
|
227
|
-
let workflowConfigSchema: ConfigSchema = $derived({
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
234
|
+
let workflowConfigSchema: ConfigSchema = $derived.by(() => {
|
|
235
|
+
const extraProps = Object.fromEntries(
|
|
236
|
+
Object.entries(workflowSettingsSchema?.properties ?? {}).filter(([k]) => {
|
|
237
|
+
if (WORKFLOW_SETTINGS_RESERVED.has(k)) {
|
|
238
|
+
logger.warn(
|
|
239
|
+
`workflowSettingsSchema: property "${k}" is reserved and will be ignored. Choose a different key.`
|
|
240
|
+
);
|
|
241
|
+
return false;
|
|
242
|
+
}
|
|
243
|
+
return true;
|
|
244
|
+
})
|
|
245
|
+
);
|
|
246
|
+
const extraRequired = (workflowSettingsSchema?.required ?? []).filter(
|
|
247
|
+
(k) => !WORKFLOW_SETTINGS_RESERVED.has(k)
|
|
248
|
+
);
|
|
249
|
+
return {
|
|
250
|
+
type: 'object' as const,
|
|
251
|
+
properties: {
|
|
252
|
+
name: {
|
|
253
|
+
type: 'string',
|
|
254
|
+
title: 'Workflow Name',
|
|
255
|
+
description: 'The name of the workflow',
|
|
256
|
+
default: ''
|
|
257
|
+
},
|
|
258
|
+
description: {
|
|
259
|
+
type: 'string',
|
|
260
|
+
title: 'Description',
|
|
261
|
+
description: 'A description of the workflow',
|
|
262
|
+
format: 'multiline',
|
|
263
|
+
default: ''
|
|
264
|
+
},
|
|
265
|
+
format: {
|
|
266
|
+
type: 'string',
|
|
267
|
+
title: 'Workflow Format',
|
|
268
|
+
description: 'The specification format for this workflow',
|
|
269
|
+
oneOf: workflowFormatRegistry.getOneOfOptions(),
|
|
270
|
+
default: 'flowdrop'
|
|
271
|
+
},
|
|
272
|
+
...extraProps
|
|
242
273
|
},
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
title: 'Workflow Format',
|
|
246
|
-
description: 'The specification format for this workflow',
|
|
247
|
-
oneOf: workflowFormatRegistry.getOneOfOptions(),
|
|
248
|
-
default: 'flowdrop'
|
|
249
|
-
}
|
|
250
|
-
},
|
|
251
|
-
required: ['name']
|
|
274
|
+
required: ['name', ...extraRequired]
|
|
275
|
+
};
|
|
252
276
|
});
|
|
253
277
|
|
|
254
278
|
// Workflow configuration values
|
|
255
279
|
let workflowConfigValues = $derived({
|
|
256
280
|
name: getWorkflowName() || '',
|
|
257
281
|
description: getWorkflowStore()?.description || '',
|
|
258
|
-
format: getWorkflowStore()?.metadata?.format || 'flowdrop'
|
|
282
|
+
format: getWorkflowStore()?.metadata?.format || 'flowdrop',
|
|
283
|
+
...(getWorkflowStore()?.config ?? {})
|
|
259
284
|
});
|
|
260
285
|
|
|
261
286
|
// Get the current node from the workflow store
|
|
@@ -727,7 +752,10 @@
|
|
|
727
752
|
|
|
728
753
|
// Ensure port compatibility checker is initialized (needed for proximity connect, etc.)
|
|
729
754
|
// mountFlowDropApp initializes this before mounting, but SvelteKit routes need it here.
|
|
730
|
-
|
|
755
|
+
// Only initialize with defaults if not already set — preserves custom port configs.
|
|
756
|
+
if (!isPortCompatibilityInitialized()) {
|
|
757
|
+
initializePortCompatibility(DEFAULT_PORT_CONFIG);
|
|
758
|
+
}
|
|
731
759
|
|
|
732
760
|
await fetchNodeTypes();
|
|
733
761
|
|
|
@@ -1055,13 +1083,16 @@
|
|
|
1055
1083
|
}
|
|
1056
1084
|
}
|
|
1057
1085
|
|
|
1086
|
+
// Extract built-in fields; everything else belongs in workflow.config
|
|
1087
|
+
const { name, description, format: _format, ...customConfig } = config;
|
|
1058
1088
|
workflowActions.batchUpdate({
|
|
1059
|
-
name:
|
|
1060
|
-
description:
|
|
1089
|
+
name: name as string,
|
|
1090
|
+
description: description as string | undefined,
|
|
1061
1091
|
metadata: {
|
|
1062
1092
|
...wf.metadata,
|
|
1063
1093
|
format: newFormat
|
|
1064
|
-
}
|
|
1094
|
+
},
|
|
1095
|
+
...(workflowSettingsSchema && { config: customConfig as Record<string, unknown> })
|
|
1065
1096
|
});
|
|
1066
1097
|
}
|
|
1067
1098
|
}}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { NodeMetadata, Workflow } from '../types/index.js';
|
|
1
|
+
import type { NodeMetadata, Workflow, ConfigSchema } from '../types/index.js';
|
|
2
2
|
import type { SwapStrategy } from '../utils/nodeSwap.js';
|
|
3
3
|
import type { EndpointConfig } from '../config/endpoints.js';
|
|
4
4
|
import type { AuthProvider } from '../types/auth.js';
|
|
@@ -61,6 +61,8 @@ interface Props {
|
|
|
61
61
|
showSettingsResetButton?: boolean;
|
|
62
62
|
/** Pluggable swap strategies — instance-scoped, checked in order */
|
|
63
63
|
swapStrategies?: SwapStrategy[];
|
|
64
|
+
/** Additional JSON Schema properties to show in the Workflow Settings panel. Values are persisted in workflow.config. */
|
|
65
|
+
workflowSettingsSchema?: ConfigSchema;
|
|
64
66
|
}
|
|
65
67
|
declare const App: import("svelte").Component<Props, {}, "">;
|
|
66
68
|
type App = ReturnType<typeof App>;
|
|
@@ -91,13 +91,14 @@
|
|
|
91
91
|
return '';
|
|
92
92
|
}
|
|
93
93
|
if (typeof val === 'string') {
|
|
94
|
-
//
|
|
94
|
+
// If the string is already a valid JSON representation (e.g. '{"a":1}' or '"foo"'),
|
|
95
|
+
// use it as-is to avoid double-encoding
|
|
95
96
|
try {
|
|
96
97
|
JSON.parse(val);
|
|
97
98
|
return val;
|
|
98
99
|
} catch {
|
|
99
|
-
//
|
|
100
|
-
return val;
|
|
100
|
+
// Plain JS string value — serialize it as a JSON string literal (adds quotes)
|
|
101
|
+
return JSON.stringify(val);
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
// Convert object to formatted JSON string
|
|
@@ -82,9 +82,7 @@
|
|
|
82
82
|
* This allows users to customize the node description per-instance via config.
|
|
83
83
|
*/
|
|
84
84
|
const displayDescription = $derived(
|
|
85
|
-
(props.data.config?.instanceDescription as string) ||
|
|
86
|
-
props.data.metadata?.description ||
|
|
87
|
-
'A configurable simple node'
|
|
85
|
+
(props.data.config?.instanceDescription as string) || props.data.metadata?.description || null
|
|
88
86
|
);
|
|
89
87
|
|
|
90
88
|
// Handle configuration sidebar - now using global ConfigSidebar
|
|
@@ -226,9 +224,11 @@
|
|
|
226
224
|
</div>
|
|
227
225
|
|
|
228
226
|
<!-- Node Description -->
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
227
|
+
{#if displayDescription}
|
|
228
|
+
<p class="flowdrop-simple-node__description">
|
|
229
|
+
{displayDescription}
|
|
230
|
+
</p>
|
|
231
|
+
{/if}
|
|
232
232
|
</div>
|
|
233
233
|
|
|
234
234
|
<!-- Processing indicator -->
|
|
@@ -281,7 +281,7 @@
|
|
|
281
281
|
cursor: pointer;
|
|
282
282
|
transition: all var(--fd-transition-fast);
|
|
283
283
|
box-shadow: var(--fd-shadow-md);
|
|
284
|
-
overflow:
|
|
284
|
+
overflow: hidden;
|
|
285
285
|
z-index: 10;
|
|
286
286
|
color: var(--fd-foreground);
|
|
287
287
|
}
|
|
@@ -328,7 +328,7 @@
|
|
|
328
328
|
.flowdrop-simple-node__header {
|
|
329
329
|
padding: var(--fd-space-xl);
|
|
330
330
|
background: var(--fd-header);
|
|
331
|
-
|
|
331
|
+
flex: 1;
|
|
332
332
|
}
|
|
333
333
|
|
|
334
334
|
.flowdrop-simple-node__header-content {
|
|
@@ -36,6 +36,11 @@
|
|
|
36
36
|
},
|
|
37
37
|
"metadata": {
|
|
38
38
|
"$ref": "#/$defs/WorkflowMetadata"
|
|
39
|
+
},
|
|
40
|
+
"config": {
|
|
41
|
+
"type": "object",
|
|
42
|
+
"description": "Custom workflow-level configuration values. Populated when a workflowSettingsSchema is provided to the editor.",
|
|
43
|
+
"additionalProperties": true
|
|
39
44
|
}
|
|
40
45
|
},
|
|
41
46
|
"required": [
|
|
@@ -263,6 +263,7 @@ export declare const workflowActions: {
|
|
|
263
263
|
name?: string;
|
|
264
264
|
description?: string;
|
|
265
265
|
metadata?: Partial<Workflow["metadata"]>;
|
|
266
|
+
config?: Record<string, unknown>;
|
|
266
267
|
}) => void;
|
|
267
268
|
/**
|
|
268
269
|
* Swap a node — atomically replaces nodes and edges with a descriptive history entry.
|
|
@@ -632,6 +632,7 @@ export const workflowActions = {
|
|
|
632
632
|
...(updates.description !== undefined && {
|
|
633
633
|
description: updates.description
|
|
634
634
|
}),
|
|
635
|
+
...(updates.config !== undefined && { config: updates.config }),
|
|
635
636
|
metadata: buildMetadata(workflowState.metadata, updates.metadata ?? undefined)
|
|
636
637
|
};
|
|
637
638
|
bumpVersion();
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1150,6 +1150,8 @@ export interface Workflow {
|
|
|
1150
1150
|
/** Workflow format. Determines sidebar filtering and export behavior. */
|
|
1151
1151
|
format?: WorkflowFormat;
|
|
1152
1152
|
};
|
|
1153
|
+
/** Custom workflow-level configuration values, populated via workflowSettingsSchema. */
|
|
1154
|
+
config?: Record<string, unknown>;
|
|
1153
1155
|
}
|
|
1154
1156
|
/**
|
|
1155
1157
|
* API response types
|
|
@@ -57,6 +57,10 @@ export declare class PortCompatibilityChecker {
|
|
|
57
57
|
* Initialize the global port compatibility checker
|
|
58
58
|
*/
|
|
59
59
|
export declare function initializePortCompatibility(portConfig: PortConfig): void;
|
|
60
|
+
/**
|
|
61
|
+
* Returns true if the port compatibility checker has been initialized.
|
|
62
|
+
*/
|
|
63
|
+
export declare function isPortCompatibilityInitialized(): boolean;
|
|
60
64
|
/**
|
|
61
65
|
* Get the global port compatibility checker
|
|
62
66
|
*/
|
|
@@ -114,6 +114,12 @@ let globalCompatibilityChecker = null;
|
|
|
114
114
|
export function initializePortCompatibility(portConfig) {
|
|
115
115
|
globalCompatibilityChecker = new PortCompatibilityChecker(portConfig);
|
|
116
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Returns true if the port compatibility checker has been initialized.
|
|
119
|
+
*/
|
|
120
|
+
export function isPortCompatibilityInitialized() {
|
|
121
|
+
return globalCompatibilityChecker !== null;
|
|
122
|
+
}
|
|
117
123
|
/**
|
|
118
124
|
* Get the global port compatibility checker
|
|
119
125
|
*/
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"description": "A drop-in visual workflow editor for any web application. You own the backend. You own the data. You own the orchestration.",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"private": false,
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.7.0",
|
|
7
7
|
"author": "Shibin Das (D34dMan)",
|
|
8
8
|
"bugs": {
|
|
9
9
|
"url": "https://github.com/flowdrop-io/flowdrop/issues"
|