0
# Composables
1
2
Vue 3 composables providing reusable functionality for canvas operations, workflow helpers, UI interactions, and common utilities.
3
4
## Capabilities
5
6
### Canvas Composables
7
8
Composables for canvas and node operations.
9
10
```typescript { .api }
11
/**
12
* Access canvas node data within node components
13
*/
14
function useCanvasNode(): UseCanvasNodeReturn;
15
16
interface UseCanvasNodeReturn {
17
node: InjectedCanvasNode;
18
id: ComputedRef<string>;
19
name: ComputedRef<string>;
20
label: ComputedRef<string>;
21
subtitle: ComputedRef<string>;
22
inputs: ComputedRef<CanvasConnectionPort[]>;
23
outputs: ComputedRef<CanvasConnectionPort[]>;
24
connections: ComputedRef<INodeConnections>;
25
isDisabled: ComputedRef<boolean>;
26
isReadOnly: ComputedRef<boolean>;
27
isSelected: ComputedRef<boolean>;
28
pinnedDataCount: ComputedRef<number>;
29
hasPinnedData: ComputedRef<boolean>;
30
runDataIterations: ComputedRef<number>;
31
runDataOutputMap: ComputedRef<Record<string, any>>;
32
hasRunData: ComputedRef<boolean>;
33
issues: ComputedRef<string[]>;
34
hasIssues: ComputedRef<boolean>;
35
executionStatus: ComputedRef<ExecutionStatus | undefined>;
36
executionWaiting: ComputedRef<string | undefined>;
37
executionWaitingForNext: ComputedRef<boolean>;
38
executionRunning: ComputedRef<boolean>;
39
render: ComputedRef<CanvasNodeRender>;
40
eventBus: ComputedRef<EventBus | undefined>;
41
}
42
43
/**
44
* Canvas operations for node manipulation
45
*/
46
function useCanvasOperations(): CanvasOperationsReturn;
47
48
interface CanvasOperationsReturn {
49
addNodes(nodes: AddedNode[], connections?: AddedNodeConnection[]): void;
50
deleteNode(id: string): void;
51
copyNodes(ids: string[]): void;
52
pasteNodes(position?: XYPosition): void;
53
createConnection(source: CanvasConnectionPort, target: CanvasConnectionPort): void;
54
updateNodePosition(id: string, position: XYPosition): void;
55
}
56
57
/**
58
* Canvas layout and arrangement
59
*/
60
function useCanvasLayout(): CanvasLayoutReturn;
61
62
interface CanvasLayoutReturn {
63
layout(target: 'all' | 'selection'): void;
64
arrangeNodes(nodes: INodeUi[], direction?: 'horizontal' | 'vertical'): INodeUi[];
65
}
66
```
67
68
### Workflow Composables
69
70
Composables for workflow operations and management.
71
72
```typescript { .api }
73
/**
74
* Workflow helper functions
75
*/
76
function useWorkflowHelpers(): WorkflowHelpersReturn;
77
78
interface WorkflowHelpersReturn {
79
getWorkflowDataToSave(): IWorkflowDataUpdate;
80
saveCurrentWorkflow(options?: { tags?: string[] }): Promise<void>;
81
getCurrentWorkflow(copyData?: boolean): Workflow;
82
initializeWorkflow(): void;
83
resolveRequiredParameters(node: INodeUi, nodeType: INodeTypeDescription): INodeParameters;
84
}
85
86
/**
87
* Workflow execution helpers
88
*/
89
function useRunWorkflow(): RunWorkflowReturn;
90
91
interface RunWorkflowReturn {
92
runWorkflowData: Ref<IStartRunData | null>;
93
isExecutionPreview: Ref<boolean>;
94
runWorkflow(data: IStartRunData): Promise<IExecutionPushResponse>;
95
stopCurrentExecution(): Promise<void>;
96
stopExecution(executionId: string): Promise<void>;
97
}
98
99
/**
100
* Workflow saving functionality
101
*/
102
function useWorkflowSaving(): WorkflowSavingReturn;
103
104
interface WorkflowSavingReturn {
105
isSaving: Ref<boolean>;
106
hasUnsavedChanges: Ref<boolean>;
107
saveWorkflow(options?: { tags?: string[]; redirect?: boolean }): Promise<void>;
108
saveAsNewWorkflow(name: string): Promise<void>;
109
}
110
```
111
112
### Node Composables
113
114
Node-specific helper composables.
115
116
```typescript { .api }
117
/**
118
* Node helper functions
119
*/
120
function useNodeHelpers(): NodeHelpersReturn;
121
122
interface NodeHelpersReturn {
123
getNodeSubtitle(node: INodeUi, nodeType?: INodeTypeDescription, workflow?: Workflow): string;
124
hasNodeCredential(node: INodeUi, credentialType: string): boolean;
125
assignNodeId(node: INodeUi): string;
126
getNodeIssues(node: INodeUi, workflow: Workflow): INodeIssues | null;
127
updateNodeParameterIssues(node: INodeUi, issues?: INodeIssues): void;
128
}
129
130
/**
131
* Node type information
132
*/
133
function useNodeType(params: { node: Ref<INodeUi | null> }): NodeTypeReturn;
134
135
interface NodeTypeReturn {
136
nodeType: ComputedRef<INodeTypeDescription | null>;
137
isSubNode: ComputedRef<boolean>;
138
isTriggerNode: ComputedRef<boolean>;
139
isConfigNode: ComputedRef<boolean>;
140
hasMultipleOutputs: ComputedRef<boolean>;
141
}
142
143
/**
144
* Node connections management
145
*/
146
function useNodeConnections(): NodeConnectionsReturn;
147
148
interface NodeConnectionsReturn {
149
getNodeConnections(nodeName: string): { input: IConnection[][]; output: IConnection[][] };
150
getChildNodes(nodeName: string): string[];
151
getParentNodes(nodeName: string): string[];
152
hasInputConnections(nodeName: string): boolean;
153
hasOutputConnections(nodeName: string): boolean;
154
}
155
```
156
157
### UI Interaction Composables
158
159
Composables for user interface interactions.
160
161
```typescript { .api }
162
/**
163
* Keyboard shortcuts management
164
*/
165
function useKeybindings(
166
keymap: MaybeRefOrGetter<KeyMap>,
167
options?: KeybindingOptions
168
): void;
169
170
interface KeyMap {
171
[key: string]: (event: KeyboardEvent) => void | boolean;
172
}
173
174
interface KeybindingOptions {
175
disabled?: MaybeRefOrGetter<boolean>;
176
preventDefault?: boolean;
177
stopPropagation?: boolean;
178
}
179
180
/**
181
* Toast notifications
182
*/
183
function useToast(): ToastReturn;
184
185
interface ToastReturn {
186
showMessage(config: NotificationOptions): void;
187
showError(error: Error | string, title?: string): void;
188
showSuccess(message: string, title?: string): void;
189
showWarning(message: string, title?: string): void;
190
showInfo(message: string, title?: string): void;
191
}
192
193
/**
194
* Loading states management
195
*/
196
function useLoadingService(): LoadingServiceReturn;
197
198
interface LoadingServiceReturn {
199
startLoading(text?: string): void;
200
stopLoading(): void;
201
setLoadingText(text: string): void;
202
}
203
204
/**
205
* Clipboard operations
206
*/
207
function useClipboard(): ClipboardReturn;
208
209
interface ClipboardReturn {
210
copy(text: string): Promise<void>;
211
paste(): Promise<string>;
212
isSupported: boolean;
213
}
214
```
215
216
### Data Management Composables
217
218
Composables for data processing and management.
219
220
```typescript { .api }
221
/**
222
* Data schema inference and handling
223
*/
224
function useDataSchema(): DataSchemaReturn;
225
226
interface DataSchemaReturn {
227
getSchemaForData(data: INodeExecutionData[]): Schema[];
228
inferSchema(value: unknown, path?: string): Schema;
229
validateDataAgainstSchema(data: unknown, schema: Schema[]): ValidationResult;
230
}
231
232
/**
233
* Pinned data management
234
*/
235
function usePinnedData(node: Ref<INodeUi>): PinnedDataReturn;
236
237
interface PinnedDataReturn {
238
pinnedData: ComputedRef<IDataObject[] | undefined>;
239
hasPinnedData: ComputedRef<boolean>;
240
setPinnedData(data: IDataObject[]): void;
241
removePinnedData(): void;
242
canPinData: ComputedRef<boolean>;
243
}
244
245
/**
246
* Expression editor functionality
247
*/
248
function useExpressionEditor(): ExpressionEditorReturn;
249
250
interface ExpressionEditorReturn {
251
segments: Ref<Segment[]>;
252
selection: Ref<Range>;
253
insertText(text: string): void;
254
insertExpression(expression: string): void;
255
getValue(): string;
256
setValue(value: string): void;
257
}
258
```
259
260
### Utility Composables
261
262
General utility composables for common functionality.
263
264
```typescript { .api }
265
/**
266
* Debounced reactive values
267
*/
268
function useDebounce<T>(value: Ref<T>, delay: number): {
269
debouncedValue: Ref<T>;
270
flush(): void;
271
cancel(): void;
272
};
273
274
/**
275
* Document title management
276
*/
277
function useDocumentTitle(): DocumentTitleReturn;
278
279
interface DocumentTitleReturn {
280
title: Ref<string>;
281
setTitle(newTitle: string): void;
282
resetTitle(): void;
283
}
284
285
/**
286
* Local storage with reactivity
287
*/
288
function useN8nLocalStorage<T>(
289
key: string,
290
defaultValue: T
291
): [Ref<T>, (value: T) => void];
292
293
/**
294
* Message handling
295
*/
296
function useMessage(): MessageReturn;
297
298
interface MessageReturn {
299
confirm(config: MessageBoxConfig): Promise<boolean>;
300
alert(config: MessageBoxConfig): Promise<void>;
301
prompt(config: MessageBoxConfig): Promise<string>;
302
}
303
304
/**
305
* External hooks integration
306
*/
307
function useExternalHooks(): ExternalHooksReturn;
308
309
interface ExternalHooksReturn {
310
run(hookName: string, ...args: any[]): Promise<void>;
311
runWithReturn<T>(hookName: string, ...args: any[]): Promise<T>;
312
}
313
```
314
315
## Usage Examples
316
317
**Canvas Node Composable:**
318
319
```vue
320
<script setup lang="ts">
321
import { useCanvasNode } from '@/composables/useCanvasNode';
322
323
// Access node data within canvas node component
324
const {
325
node,
326
name,
327
label,
328
inputs,
329
outputs,
330
isSelected,
331
hasIssues,
332
executionRunning
333
} = useCanvasNode();
334
335
// Reactive node properties
336
watchEffect(() => {
337
if (hasIssues.value) {
338
console.warn(`Node ${name.value} has issues`);
339
}
340
});
341
</script>
342
```
343
344
**Keyboard Bindings:**
345
346
```typescript
347
import { useKeybindings } from '@/composables/useKeybindings';
348
349
// Define keyboard shortcuts
350
const keyMap = {
351
'ctrl+s': () => saveWorkflow(),
352
'ctrl+z': () => undo(),
353
'ctrl+y': () => redo(),
354
'delete': () => deleteSelectedNodes(),
355
'ctrl+c': () => copyNodes(),
356
'ctrl+v': () => pasteNodes(),
357
'escape': () => deselectAll()
358
};
359
360
// Apply keybindings with options
361
useKeybindings(keyMap, {
362
disabled: computed(() => isModalOpen.value),
363
preventDefault: true
364
});
365
```
366
367
**Toast Notifications:**
368
369
```typescript
370
import { useToast } from '@/composables/useToast';
371
372
const toast = useToast();
373
374
// Show different types of notifications
375
const handleSuccess = () => {
376
toast.showSuccess('Workflow saved successfully!');
377
};
378
379
const handleError = (error: Error) => {
380
toast.showError(error, 'Failed to save workflow');
381
};
382
383
const handleCustomMessage = () => {
384
toast.showMessage({
385
message: 'Custom notification',
386
type: 'info',
387
duration: 5000,
388
showClose: true
389
});
390
};
391
```
392
393
**Data Schema Usage:**
394
395
```typescript
396
import { useDataSchema } from '@/composables/useDataSchema';
397
398
const { getSchemaForData, inferSchema } = useDataSchema();
399
400
// Infer schema from execution data
401
const executionData = [
402
{ json: { id: 1, name: 'John', active: true } },
403
{ json: { id: 2, name: 'Jane', active: false } }
404
];
405
406
const schema = getSchemaForData(executionData);
407
console.log(schema); // Inferred schema structure
408
```
409
410
## Types
411
412
```typescript { .api }
413
interface Segment {
414
kind: SegmentKind;
415
content: string;
416
from: number;
417
to: number;
418
}
419
420
enum SegmentKind {
421
Text = 'text',
422
Expression = 'expression',
423
Resolvable = 'resolvable'
424
}
425
426
interface Range {
427
from: number;
428
to: number;
429
}
430
431
interface Schema {
432
type: SchemaType;
433
key?: string;
434
value: string | Schema[];
435
path: string;
436
}
437
438
type SchemaType =
439
| 'string'
440
| 'number'
441
| 'boolean'
442
| 'array'
443
| 'object'
444
| 'null'
445
| 'undefined';
446
447
interface ValidationResult {
448
isValid: boolean;
449
errors: string[];
450
}
451
452
interface NotificationOptions {
453
message: string;
454
title?: string;
455
type?: 'success' | 'warning' | 'info' | 'error';
456
duration?: number;
457
showClose?: boolean;
458
offset?: number;
459
onClose?: () => void;
460
}
461
462
interface MessageBoxConfig {
463
title?: string;
464
message: string;
465
type?: 'success' | 'warning' | 'info' | 'error';
466
confirmButtonText?: string;
467
cancelButtonText?: string;
468
showCancelButton?: boolean;
469
dangerouslyUseHTMLString?: boolean;
470
}
471
472
type MaybeRefOrGetter<T> = T | Ref<T> | (() => T);
473
```