@flowdrop/flowdrop 2.0.0-beta.1 → 2.0.0-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/MIGRATION-2.0.md +160 -3
  3. package/dist/api/enhanced-client.js +6 -11
  4. package/dist/components/App.svelte +1 -0
  5. package/dist/components/ConfigForm.svelte +6 -2
  6. package/dist/components/PipelineStatus.svelte +6 -1
  7. package/dist/components/PipelineStatus.svelte.d.ts +3 -0
  8. package/dist/components/SchemaForm.svelte +4 -2
  9. package/dist/components/WorkflowEditor.svelte +4 -1
  10. package/dist/components/WorkflowEditor.svelte.d.ts +3 -0
  11. package/dist/components/chat/AIChatPanel.svelte +6 -1
  12. package/dist/components/form/FormAutocomplete.svelte +8 -9
  13. package/dist/components/form/FormFieldLight.svelte +30 -1
  14. package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
  15. package/dist/components/form/FormUISchemaRenderer.svelte +3 -1
  16. package/dist/components/interrupt/InterruptBubble.svelte +11 -2
  17. package/dist/components/playground/PipelineKanbanView.svelte +4 -2
  18. package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
  19. package/dist/components/playground/PipelinePanel.svelte +20 -3
  20. package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
  21. package/dist/components/playground/PipelineTableView.svelte +4 -2
  22. package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
  23. package/dist/components/playground/Playground.svelte +76 -25
  24. package/dist/components/playground/Playground.svelte.d.ts +3 -0
  25. package/dist/components/playground/PlaygroundApp.svelte +5 -0
  26. package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
  27. package/dist/components/playground/PlaygroundModal.svelte +5 -0
  28. package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
  29. package/dist/components/playground/PlaygroundStudio.svelte +7 -1
  30. package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
  31. package/dist/components/playground/pipelineViewUtils.svelte.d.ts +2 -1
  32. package/dist/components/playground/pipelineViewUtils.svelte.js +2 -2
  33. package/dist/config/endpoints.d.ts +23 -0
  34. package/dist/config/endpoints.js +28 -0
  35. package/dist/core/index.d.ts +1 -2
  36. package/dist/core/index.js +2 -6
  37. package/dist/display/index.d.ts +6 -1
  38. package/dist/display/index.js +9 -1
  39. package/dist/editor/index.d.ts +1 -1
  40. package/dist/editor/index.js +1 -1
  41. package/dist/form/full.d.ts +2 -1
  42. package/dist/form/full.js +4 -1
  43. package/dist/form/index.d.ts +0 -1
  44. package/dist/form/index.js +3 -2
  45. package/dist/helpers/workflowEditorHelper.d.ts +4 -2
  46. package/dist/helpers/workflowEditorHelper.js +4 -3
  47. package/dist/playground/index.d.ts +2 -2
  48. package/dist/playground/index.js +2 -2
  49. package/dist/playground/mount.d.ts +10 -0
  50. package/dist/playground/mount.js +8 -4
  51. package/dist/registry/builtinNodeTypes.d.ts +53 -0
  52. package/dist/registry/builtinNodeTypes.js +67 -0
  53. package/dist/registry/builtinNodes.d.ts +2 -39
  54. package/dist/registry/builtinNodes.js +6 -53
  55. package/dist/services/agentSpecExecutionService.d.ts +0 -2
  56. package/dist/services/agentSpecExecutionService.js +0 -2
  57. package/dist/services/apiVariableService.js +12 -26
  58. package/dist/services/categoriesApi.js +3 -6
  59. package/dist/services/chatService.d.ts +4 -3
  60. package/dist/services/chatService.js +13 -18
  61. package/dist/services/interruptService.d.ts +7 -6
  62. package/dist/services/interruptService.js +19 -21
  63. package/dist/services/playgroundService.d.ts +9 -8
  64. package/dist/services/playgroundService.js +23 -25
  65. package/dist/services/portConfigApi.js +3 -6
  66. package/dist/services/settingsService.d.ts +9 -4
  67. package/dist/services/settingsService.js +23 -12
  68. package/dist/stores/apiContext.d.ts +11 -0
  69. package/dist/stores/apiContext.js +15 -0
  70. package/dist/stores/categoriesStore.svelte.js +0 -1
  71. package/dist/stores/playgroundStore.svelte.js +0 -2
  72. package/dist/svelte-app.js +2 -1
  73. package/dist/types/auth.d.ts +9 -51
  74. package/dist/types/auth.js +4 -54
  75. package/dist/types/index.d.ts +4 -2
  76. package/dist/types/index.js +0 -1
  77. package/dist/utils/edgeStyling.js +9 -5
  78. package/dist/utils/fetchWithAuth.d.ts +36 -15
  79. package/dist/utils/fetchWithAuth.js +53 -23
  80. package/dist/utils/nodeTypes.js +1 -1
  81. package/package.json +2 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [2.0.0-beta.2] - 2026-06-09
11
+
12
+ Second 2.0 beta, published under the npm `beta` dist-tag (`npm install @flowdrop/flowdrop@beta`). This release tightens the 2.0 package boundaries, finishes `AuthProvider` propagation across the editor and playground runtime surfaces, and adds a regression guard for light-entry bundle size.
13
+
14
+ ### Breaking Changes
15
+
16
+ - **Heavy dependencies no longer leak into the light entries.** Three exports moved so that `@flowdrop/flowdrop/core` and the light `@flowdrop/flowdrop/form` never statically pull CodeMirror, `marked`, DOMPurify, or `@xyflow/svelte` (enforced by a new CI bundle guard, see below):
17
+ - `sanitizeHtml` moved from `@flowdrop/flowdrop/core` to `@flowdrop/flowdrop/display` (it is DOMPurify-backed; `/core` is the zero-heavy-dep entry).
18
+ - `FormFieldFull` moved from `@flowdrop/flowdrop/form` to `@flowdrop/flowdrop/form/full` — it statically bundles every editor (CodeMirror), so keeping it in the light `/form` entry pulled CodeMirror into every `SchemaForm` import. The `FormField` exported from `/form` remains the registry-based light factory.
19
+ - Service singleton _instances_ (`playgroundService`, `interruptService` from `/playground`; `nodeExecutionService` from `/editor`; `agentSpecExecutionService` from `/core`) are no longer exported — they were constructed eagerly at import time, pulling the service and its dependencies into the entry's static graph. The classes (`PlaygroundService`, `InterruptService`, `NodeExecutionService`, `AgentSpecExecutionService`) remain; call `getInstance()` for the shared instance. See [MIGRATION-2.0.md section 4](./MIGRATION-2.0.md#keeping-heavy-dependencies-out-of-the-light-entries).
20
+
21
+ ### Changed (internal — no API change)
22
+
23
+ - `SchemaForm`, `ConfigForm`, and the UISchema renderer now use the registry-based light `FormFieldLight` internally, so importing `SchemaForm` no longer statically pulls CodeMirror (heavy editors stay opt-in via `/form/code` and `/form/markdown`).
24
+ - Built-in node **type metadata** (aliases, `resolveBuiltinAlias`, `isBuiltinType`) split into a component-free `registry/builtinNodeTypes` module so `/core`'s node-type utilities no longer drag in the node components (and transitively `marked`/DOMPurify).
25
+ - `utils/edgeStyling` and the `ConnectionLineType` reference in `types/index.ts` use type-only imports of `@xyflow/svelte`, removing the runtime `@xyflow/svelte` dependency from the headless command DSL reachable from `/core`.
26
+
27
+ ### Added
28
+
29
+ - **Bundle-size guard (`pnpm run check:bundle`)** and a CI workflow that walk each published entry's static import graph and fail if a heavy dependency (CodeMirror, `@xyflow/svelte`, `marked`, DOMPurify) becomes statically reachable from a light entry (`/core`, `/form`, `/editor`). Dynamic `import()` — how `/form/code` lazy-loads CodeMirror — is intentionally ignored.
30
+ - **500-node editor render benchmark.** The e2e performance suite now includes a large trigger-chain workflow fixture so regressions in large-canvas rendering show up before release.
31
+
32
+ ### Fixed
33
+
34
+ - **`AuthProvider` now reaches all documented runtime surfaces.** Playground, chat, interrupt, settings, editor, and pipeline requests now consistently route through the configured provider, including standalone playground mounts and the editor/pipeline views that previously dropped auth headers on secondary requests.
35
+ - **Theme skin tokens clear when switching back to the default skin.** Returning from a custom/base skin to the default theme no longer leaves stale CSS custom properties behind.
36
+
37
+ ### Changed
38
+
39
+ - **`AuthProvider` request handling is centralized.** Services now share the `fetchWithAuth` path, and the public provider interface is slimmer while preserving bearer, API-key, custom-header, and callback authentication behavior.
40
+
8
41
  ## [2.0.0-beta.1] - 2026-06-07
9
42
 
10
43
  Pre-release of 2.0.0, published under the npm `beta` dist-tag (`npm install @flowdrop/flowdrop@beta`). `latest` remains 1.15.0 until 2.0.0 GA. See [MIGRATION-2.0.md](./MIGRATION-2.0.md) for the upgrade guide.
package/MIGRATION-2.0.md CHANGED
@@ -80,6 +80,52 @@ authProvider)` for you. Services that previously read the singleton (playground,
80
80
  interrupt, chat, node-execution, dynamic-schema, variable) now take the endpoint
81
81
  config as their first argument — pass `fd.api.config`.
82
82
 
83
+ These services also accept the instance's `AuthProvider` as an **optional
84
+ trailing argument** so every request they make is authenticated consistently
85
+ with `fd.api.client` (the typed workflow/node API). The built-in components and
86
+ mount helpers pass `fd.api.authProvider` for you — no action is needed for the
87
+ normal mounted flow. Only direct callers of the service singletons need to
88
+ forward it:
89
+
90
+ ```js
91
+ import { playgroundService } from '@flowdrop/flowdrop/playground';
92
+
93
+ // 2.0 — authenticate playground requests by forwarding the provider
94
+ await playgroundService.listSessions(fd.api.config, workflowId, undefined, fd.api.authProvider);
95
+ await playgroundService.sendMessage(fd.api.config, sessionId, text, undefined, fd.api.authProvider);
96
+ ```
97
+
98
+ The settings-sync entry points gained the same optional provider:
99
+ `setSettingsEndpointConfig(config, authProvider?)` and
100
+ `createSettingsService(config, authProvider?)` — pass an `AuthProvider` if your
101
+ backend's preferences endpoint requires auth.
102
+
103
+ The standalone playground mounts — `mountPlayground`, `mountPlaygroundStudio`,
104
+ and `mountPlaygroundApp` — accept an `authProvider` option that they wire into
105
+ `fd.api` for you (the editor's built-in playground already inherits the
106
+ provider from `mountFlowDropApp`). Pass it so playground requests (sessions,
107
+ messages, polling, interrupts) carry your auth/CSRF headers:
108
+
109
+ ```js
110
+ mountPlayground(el, {
111
+ workflowId,
112
+ endpointConfig: createEndpointConfig('/api/flowdrop'),
113
+ authProvider: new CallbackAuthProvider({ getToken: () => session.getCsrfToken() })
114
+ });
115
+ ```
116
+
117
+ The same plumbing was extended to the editor and pipeline surfaces, which
118
+ previously built unauthenticated API clients from `endpointConfig` alone:
119
+
120
+ - The exported `<WorkflowEditor>` component accepts an `authProvider` prop
121
+ (threaded for you by `mountFlowDropApp` / `mountWorkflowEditor` / `<App>`).
122
+ Pass it when using `<WorkflowEditor>` directly.
123
+ - `<PipelineStatus>` accepts an `authProvider` prop (used when it builds its own
124
+ client from `endpointConfig` / `baseUrl`; ignored when you pass `apiClient`).
125
+ - `PipelineViewProps` — the contract for custom pipeline views registered via
126
+ `pipelineViews` — gained an optional `authProvider`, so custom views can build
127
+ authenticated clients the same way the built-in graph/kanban/table views do.
128
+
83
129
  ### `EndpointConfig.auth` is removed — use an `AuthProvider`
84
130
 
85
131
  The `auth` block on `EndpointConfig` (and its header-injection branch) is gone.
@@ -108,6 +154,65 @@ mountFlowDropApp(el, {
108
154
  | `{ type: 'api_key', apiKey }` | `new StaticAuthProvider({ type: 'api_key', apiKey })` |
109
155
  | `{ type: 'custom', headers }` | `new StaticAuthProvider({ type: 'custom', headers })` |
110
156
 
157
+ `StaticAuthProvider`'s `api_key` type now accepts an optional `apiKeyHeader` to
158
+ override the header name (defaults to `X-API-Key`):
159
+
160
+ ```js
161
+ new StaticAuthProvider({ type: 'api_key', apiKey: KEY, apiKeyHeader: 'X-Tenant-Key' });
162
+ ```
163
+
164
+ ### `AuthProvider.isAuthenticated()` is removed
165
+
166
+ The `isAuthenticated()` method has been dropped from the `AuthProvider`
167
+ interface and all built-in providers. It was never consulted by the library —
168
+ request authentication is driven entirely by `getAuthHeaders()` and the optional
169
+ `onUnauthorized()` / `onForbidden()` hooks. If you implemented a **custom**
170
+ `AuthProvider`, you can delete the method; no replacement is needed.
171
+
172
+ ```ts
173
+ // 1.x — required
174
+ const provider: AuthProvider = {
175
+ getAuthHeaders: async () => ({ Authorization: `Bearer ${token}` }),
176
+ isAuthenticated: () => Boolean(token) // ← remove this
177
+ };
178
+
179
+ // 2.0
180
+ const provider: AuthProvider = {
181
+ getAuthHeaders: async () => ({ Authorization: `Bearer ${token}` })
182
+ };
183
+ ```
184
+
185
+ ### Auth refresh (`401`) now applies to every request
186
+
187
+ Previously only the typed workflow/node API (`fd.api.client`) refreshed and
188
+ retried on `401`. The per-instance services (playground, chat, interrupt,
189
+ settings, port config, categories) and form autocomplete attached auth headers
190
+ but did **not** invoke `onUnauthorized()`. They now all route through one
191
+ authenticated-fetch path, so a configured `onUnauthorized()` fires — and the
192
+ request retries once with a refreshed token — uniformly across the library.
193
+
194
+ This is not a source change for consumers, but if your `onUnauthorized()` had
195
+ side effects (analytics, redirects) it may now be called from request paths
196
+ where it previously was not. Make it idempotent.
197
+
198
+ ### Swap the auth provider at runtime — `fd.api.setAuthProvider()`
199
+
200
+ The `AuthProvider` is still supplied at mount time, but you no longer have to
201
+ remount to change it (e.g. on login/logout). `ApiContext` gained
202
+ `setAuthProvider()`, which updates the live client and is picked up by services
203
+ on their next request:
204
+
205
+ ```js
206
+ import { getInstance } from '@flowdrop/flowdrop/editor';
207
+ const fd = getInstance();
208
+
209
+ // after the user logs in / refreshes their session
210
+ fd.api.setAuthProvider(new StaticAuthProvider({ type: 'bearer', token: newToken }));
211
+
212
+ // on logout
213
+ fd.api.setAuthProvider(new NoAuthProvider());
214
+ ```
215
+
111
216
  ### Instance-scoped port compatibility
112
217
 
113
218
  `initializePortCompatibility()`, `getPortCompatibilityChecker()`, and
@@ -206,16 +311,16 @@ barrel no longer re-exports `marked`.
206
311
 
207
312
  - **Playground exports** (`Playground`, `PlaygroundModal`, `ChatPanel`,
208
313
  `SessionManager`, `InputCollector`, `ExecutionLogs`, `MessageBubble`,
209
- `PlaygroundService`, `playgroundService`, `PlaygroundStore`) are removed from
314
+ `PlaygroundService`, `PlaygroundStore`) are removed from
210
315
  `@flowdrop/flowdrop/editor`. Import them from `@flowdrop/flowdrop/playground`
211
316
  instead.
212
317
 
213
318
  ```js
214
319
  // 1.x
215
- import { Playground, playgroundService } from '@flowdrop/flowdrop/editor';
320
+ import { Playground, PlaygroundStore } from '@flowdrop/flowdrop/editor';
216
321
 
217
322
  // 2.0
218
- import { Playground, playgroundService } from '@flowdrop/flowdrop/playground';
323
+ import { Playground, PlaygroundStore } from '@flowdrop/flowdrop/playground';
219
324
  ```
220
325
 
221
326
  - **`marked`** is no longer re-exported from `@flowdrop/flowdrop/display`. If you
@@ -284,6 +389,58 @@ This also tightens tree-shaking: importing `App` and a couple of types from the
284
389
  main entry no longer pulls the form, display, playground, and settings barrels
285
390
  into your bundle.
286
391
 
392
+ ### Keeping heavy dependencies out of the light entries
393
+
394
+ A few more exports moved so that the lightweight entries (`/core`, the light
395
+ `/form`) never statically pull a heavy dependency (CodeMirror, `marked`,
396
+ DOMPurify, `@xyflow/svelte`). These are enforced by a bundle guard in CI, so
397
+ they cannot silently regress.
398
+
399
+ - **`sanitizeHtml` moved from `@flowdrop/flowdrop/core` to
400
+ `@flowdrop/flowdrop/display`.** It is DOMPurify-backed, and `/core` is the
401
+ "zero heavy dependencies" entry, so it now lives alongside `MarkdownDisplay`.
402
+
403
+ ```js
404
+ // before
405
+ import { sanitizeHtml } from '@flowdrop/flowdrop/core';
406
+ // 2.0
407
+ import { sanitizeHtml } from '@flowdrop/flowdrop/display';
408
+ ```
409
+
410
+ - **`FormFieldFull` moved from `@flowdrop/flowdrop/form` to
411
+ `@flowdrop/flowdrop/form/full`.** `FormFieldFull` statically bundles every
412
+ editor (including CodeMirror); keeping it in the light `/form` entry pulled
413
+ CodeMirror into every `SchemaForm` import. The default `FormField` exported
414
+ from `/form` is the registry-based light field factory — register heavy
415
+ editors via `/form/code` / `/form/markdown` (unchanged). Use `/form/full`
416
+ only if you specifically want every editor statically bundled.
417
+
418
+ ```js
419
+ // before
420
+ import { FormFieldFull } from '@flowdrop/flowdrop/form';
421
+ // 2.0
422
+ import { FormFieldFull } from '@flowdrop/flowdrop/form/full';
423
+ ```
424
+
425
+ - **Service singleton _instances_ are no longer exported.**
426
+ `playgroundService` and `interruptService` (`@flowdrop/flowdrop/playground`),
427
+ `nodeExecutionService` (`@flowdrop/flowdrop/editor`), and
428
+ `agentSpecExecutionService` (`@flowdrop/flowdrop/core`) are removed. They were
429
+ module-level instances constructed at import time, which forced the service
430
+ (and its dependencies) to be built the moment the entry was imported. The
431
+ **classes** remain exported (`PlaygroundService`, `InterruptService`,
432
+ `NodeExecutionService`, `AgentSpecExecutionService`). Most apps never touched
433
+ these directly (use `fd.playground` / `fd.interrupts`); if you did, call
434
+ `getInstance()` to obtain the shared instance:
435
+
436
+ ```js
437
+ // before
438
+ import { playgroundService } from '@flowdrop/flowdrop/playground';
439
+ // 2.0
440
+ import { PlaygroundService } from '@flowdrop/flowdrop/playground';
441
+ const playgroundService = PlaygroundService.getInstance();
442
+ ```
443
+
287
444
  ## 5. Workflow `metadata` is required and `version` → `schemaVersion`
288
445
 
289
446
  The workflow document's `metadata` object is now **required** on the `Workflow`
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * @module api/enhanced-client
7
7
  */
8
- import { buildEndpointUrl, getEndpointMethod, getEndpointHeaders } from '../config/endpoints.js';
8
+ import { buildEndpointUrl, getEndpointMethod, getRequestHeaders } from '../config/endpoints.js';
9
9
  import { NoAuthProvider } from '../types/auth.js';
10
10
  import { getApiSettings } from '../stores/settingsStore.svelte.js';
11
11
  import { logger } from '../utils/logger.js';
@@ -56,15 +56,12 @@ export class EnhancedFlowDropApiClient {
56
56
  async request(endpointKey, endpointPath, params, options = {}, operation = 'API request') {
57
57
  const url = buildEndpointUrl(this.config, endpointPath, params);
58
58
  const method = options.method ?? getEndpointMethod(this.config, endpointKey);
59
- const configHeaders = getEndpointHeaders(this.config, endpointKey);
60
59
  // Get user settings for timeout and retry
61
60
  const userApiSettings = getApiSettings();
62
- // Get auth headers from provider
63
- const authHeaders = await this.authProvider.getAuthHeaders();
64
- // Merge headers: config headers < auth headers < request-specific headers
61
+ // Merge headers via the shared path: static endpoint headers < auth headers
62
+ // < request-specific headers.
65
63
  const headers = {
66
- ...configHeaders,
67
- ...authHeaders,
64
+ ...(await getRequestHeaders(this.config, endpointKey, this.authProvider)),
68
65
  ...options.headers
69
66
  };
70
67
  // Create AbortController for timeout
@@ -93,11 +90,9 @@ export class EnhancedFlowDropApiClient {
93
90
  if (this.authProvider.onUnauthorized) {
94
91
  const refreshed = await this.authProvider.onUnauthorized();
95
92
  if (refreshed && attempt < maxAttempts) {
96
- // Get new auth headers and retry
97
- const newAuthHeaders = await this.authProvider.getAuthHeaders();
93
+ // Rebuild headers via the shared path to pick up the fresh token.
98
94
  fetchConfig.headers = {
99
- ...configHeaders,
100
- ...newAuthHeaders,
95
+ ...(await getRequestHeaders(this.config, endpointKey, this.authProvider)),
101
96
  ...options.headers
102
97
  };
103
98
  continue; // Retry with new headers
@@ -1295,6 +1295,7 @@
1295
1295
  <WorkflowEditor
1296
1296
  bind:this={workflowEditorRef}
1297
1297
  endpointConfig={endpointConfig ?? undefined}
1298
+ {authProvider}
1298
1299
  {openConfigSidebar}
1299
1300
  {mode}
1300
1301
  {pipelineId}
@@ -32,9 +32,13 @@
32
32
  } from '../types/index.js';
33
33
  import { dynamicPortToNodePort } from '../types/index.js';
34
34
  import type { UISchemaElement } from '../types/uischema.js';
35
- import { FormField, FormFieldWrapper, FormToggle } from './form/index.js';
35
+ // Import the light, registry-based field factory and light fields directly
36
+ // (not via the form barrel, which aggregates the heavy CodeMirror editors).
37
+ import FormField from './form/FormFieldLight.svelte';
38
+ import FormFieldWrapper from './form/FormFieldWrapper.svelte';
39
+ import FormToggle from './form/FormToggle.svelte';
36
40
  import FormUISchemaRenderer from './form/FormUISchemaRenderer.svelte';
37
- import type { FieldSchema } from './form/index.js';
41
+ import type { FieldSchema } from './form/types.js';
38
42
  import {
39
43
  getEffectiveConfigEditOptions,
40
44
  fetchDynamicSchema,
@@ -12,6 +12,7 @@
12
12
  import { createEndpointConfig } from '../config/endpoints.js';
13
13
  import type { Workflow } from '../types/index.js';
14
14
  import type { EndpointConfig } from '../config/endpoints.js';
15
+ import type { AuthProvider } from '../types/auth.js';
15
16
  import { logger } from '../utils/logger.js';
16
17
  import { m } from '../messages/index.js';
17
18
 
@@ -21,6 +22,8 @@
21
22
  apiClient?: EnhancedFlowDropApiClient;
22
23
  baseUrl?: string;
23
24
  endpointConfig?: EndpointConfig;
25
+ /** Auth provider used when this component builds its own API client from endpointConfig/baseUrl. */
26
+ authProvider?: AuthProvider;
24
27
  runLabel?: string;
25
28
  /** When true, suppresses breadcrumb and layout events (used inside playground panel) */
26
29
  isEmbedded?: boolean;
@@ -43,6 +46,7 @@
43
46
  apiClient,
44
47
  baseUrl,
45
48
  endpointConfig,
49
+ authProvider,
46
50
  onActionsReady,
47
51
  runLabel,
48
52
  isEmbedded = false,
@@ -59,7 +63,8 @@
59
63
  const client =
60
64
  apiClient ||
61
65
  new EnhancedFlowDropApiClient(
62
- endpointConfig ?? createEndpointConfig(baseUrl || '/api/flowdrop')
66
+ endpointConfig ?? createEndpointConfig(baseUrl || '/api/flowdrop'),
67
+ authProvider
63
68
  );
64
69
 
65
70
  // Pipeline status — drives breadcrumb label and the 5s poll while running
@@ -1,12 +1,15 @@
1
1
  import { EnhancedFlowDropApiClient } from '../api/enhanced-client.js';
2
2
  import type { Workflow } from '../types/index.js';
3
3
  import type { EndpointConfig } from '../config/endpoints.js';
4
+ import type { AuthProvider } from '../types/auth.js';
4
5
  interface Props {
5
6
  pipelineId: string;
6
7
  workflow: Workflow;
7
8
  apiClient?: EnhancedFlowDropApiClient;
8
9
  baseUrl?: string;
9
10
  endpointConfig?: EndpointConfig;
11
+ /** Auth provider used when this component builds its own API client from endpointConfig/baseUrl. */
12
+ authProvider?: AuthProvider;
10
13
  runLabel?: string;
11
14
  /** When true, suppresses breadcrumb and layout events (used inside playground panel) */
12
15
  isEmbedded?: boolean;
@@ -59,9 +59,11 @@
59
59
  import type { ConfigSchema, AuthProvider } from '../types/index.js';
60
60
  import type { UISchemaElement } from '../types/uischema.js';
61
61
  import { provideInstance } from '../stores/getInstance.svelte.js';
62
- import { FormField } from './form/index.js';
62
+ // Registry-based light field factory — heavy editors (CodeMirror) are resolved
63
+ // at runtime via fd.fields, so importing SchemaForm never statically pulls them.
64
+ import FormField from './form/FormFieldLight.svelte';
63
65
  import FormUISchemaRenderer from './form/FormUISchemaRenderer.svelte';
64
- import type { FieldSchema } from './form/index.js';
66
+ import type { FieldSchema } from './form/types.js';
65
67
  import { m } from '../messages/index.js';
66
68
  import { mergeWithDefaults, cascadeClearAutocompleteDependents } from '../utils/formMerge.js';
67
69
 
@@ -28,6 +28,7 @@
28
28
  import EdgeRefresher from './EdgeRefresher.svelte';
29
29
  import { tick, untrack } from 'svelte';
30
30
  import type { EndpointConfig } from '../config/endpoints.js';
31
+ import type { AuthProvider } from '../types/auth.js';
31
32
  import ConnectionLine from './ConnectionLine.svelte';
32
33
  import FlowDropEdge from './FlowDropEdge.svelte';
33
34
  import { m } from '../messages/index.js';
@@ -60,6 +61,8 @@
60
61
 
61
62
  interface Props {
62
63
  endpointConfig?: EndpointConfig;
64
+ /** Auth provider applied to this instance's API requests. */
65
+ authProvider?: AuthProvider;
63
66
  openConfigSidebar?: (node: WorkflowNodeType) => void;
64
67
  /**
65
68
  * Editor interaction mode. `'edit'` allows node drag/connect/select and
@@ -596,7 +599,7 @@
596
599
  // Configure endpoints when props change
597
600
  $effect(() => {
598
601
  if (props.endpointConfig) {
599
- ConfigurationHelper.configureEndpoints(fd.api, props.endpointConfig);
602
+ ConfigurationHelper.configureEndpoints(fd.api, props.endpointConfig, props.authProvider);
600
603
  }
601
604
  });
602
605
 
@@ -1,9 +1,12 @@
1
1
  import '@xyflow/svelte/dist/style.css';
2
2
  import type { WorkflowNode as WorkflowNodeType } from '../types/index.js';
3
3
  import type { EndpointConfig } from '../config/endpoints.js';
4
+ import type { AuthProvider } from '../types/auth.js';
4
5
  import type { FlowDropInstance } from '../stores/instanceContainer.svelte.js';
5
6
  interface Props {
6
7
  endpointConfig?: EndpointConfig;
8
+ /** Auth provider applied to this instance's API requests. */
9
+ authProvider?: AuthProvider;
7
10
  openConfigSidebar?: (node: WorkflowNodeType) => void;
8
11
  /**
9
12
  * Editor interaction mode. `'edit'` allows node drag/connect/select and
@@ -369,7 +369,12 @@
369
369
  history: history.slice(0, -1) // all except current message
370
370
  };
371
371
 
372
- const response = await chatService.sendMessage(fd.api.config, workflowId, request);
372
+ const response = await chatService.sendMessage(
373
+ fd.api.config,
374
+ workflowId,
375
+ request,
376
+ fd.api.authProvider
377
+ );
373
378
  const displayMsg = processResponse(response.content);
374
379
  displayMessages.push(displayMsg);
375
380
  } catch (err) {
@@ -25,7 +25,7 @@
25
25
  import Icon from '@iconify/svelte';
26
26
  import type { AutocompleteConfig, AuthProvider } from '../../types/index.js';
27
27
  import type { FieldOption } from './types.js';
28
- import { buildFetchHeaders } from '../../utils/fetchWithAuth.js';
28
+ import { authenticatedFetch } from '../../utils/fetchWithAuth.js';
29
29
  import { logger } from '../../utils/logger.js';
30
30
  import { m } from '../../messages/index.js';
31
31
 
@@ -245,16 +245,15 @@
245
245
 
246
246
  let timeoutId: ReturnType<typeof setTimeout> | null = null;
247
247
  try {
248
- // Build headers with authentication (call getter to get current value)
249
- const headers = await buildFetchHeaders(getAuthProvider?.());
250
-
251
248
  timeoutId = setTimeout(() => controller.abort(), 5000);
252
249
 
253
- const response = await fetch(buildUrl(query), {
254
- method: 'GET',
255
- headers,
256
- signal: controller.signal
257
- });
250
+ // authenticatedFetch merges auth headers (call getter for current value)
251
+ // and applies the 401/403 lifecycle consistently with the rest of the lib.
252
+ const response = await authenticatedFetch(
253
+ buildUrl(query),
254
+ { method: 'GET', signal: controller.signal },
255
+ { authProvider: getAuthProvider?.() }
256
+ );
258
257
 
259
258
  if (!response.ok) {
260
259
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
@@ -48,6 +48,8 @@
48
48
  const fd = getInstance();
49
49
  import type { FieldSchema } from './types.js';
50
50
  import { getSchemaOptions } from './types.js';
51
+ import type { WorkflowNode, WorkflowEdge } from '../../types/index.js';
52
+ import type { AuthProvider } from '../../types/auth.js';
51
53
 
52
54
  interface Props {
53
55
  /** Unique key/id for the field */
@@ -60,11 +62,33 @@
60
62
  required?: boolean;
61
63
  /** Animation delay index for staggered animations */
62
64
  animationIndex?: number;
65
+ /** Current workflow node (optional, forwarded to registered editors for template variable API mode) */
66
+ node?: WorkflowNode;
67
+ /** All workflow nodes (optional, forwarded to registered editors for port-derived variables) */
68
+ nodes?: WorkflowNode[];
69
+ /** All workflow edges (optional, forwarded to registered editors for port-derived variables) */
70
+ edges?: WorkflowEdge[];
71
+ /** Workflow ID (optional, forwarded to registered editors for template variable API mode) */
72
+ workflowId?: string;
73
+ /** Auth provider (optional, forwarded to registered editors for API requests) */
74
+ authProvider?: AuthProvider;
63
75
  /** Callback when the field value changes */
64
76
  onChange: (value: unknown) => void;
65
77
  }
66
78
 
67
- let { fieldKey, schema, value, required = false, animationIndex = 0, onChange }: Props = $props();
79
+ let {
80
+ fieldKey,
81
+ schema,
82
+ value,
83
+ required = false,
84
+ animationIndex = 0,
85
+ node,
86
+ nodes,
87
+ edges,
88
+ workflowId,
89
+ authProvider,
90
+ onChange
91
+ }: Props = $props();
68
92
 
69
93
  /**
70
94
  * Computed description ID for ARIA association
@@ -246,6 +270,11 @@
246
270
  variables={schema.variables}
247
271
  placeholderExample={schema.placeholderExample as string | undefined}
248
272
  autocomplete={schema.autocomplete}
273
+ {node}
274
+ {nodes}
275
+ {edges}
276
+ {workflowId}
277
+ {authProvider}
249
278
  onChange={(val: unknown) => onChange(val)}
250
279
  />
251
280
  {:else if fieldType === 'checkbox-group'}
@@ -1,4 +1,6 @@
1
1
  import type { FieldSchema } from './types.js';
2
+ import type { WorkflowNode, WorkflowEdge } from '../../types/index.js';
3
+ import type { AuthProvider } from '../../types/auth.js';
2
4
  interface Props {
3
5
  /** Unique key/id for the field */
4
6
  fieldKey: string;
@@ -10,6 +12,16 @@ interface Props {
10
12
  required?: boolean;
11
13
  /** Animation delay index for staggered animations */
12
14
  animationIndex?: number;
15
+ /** Current workflow node (optional, forwarded to registered editors for template variable API mode) */
16
+ node?: WorkflowNode;
17
+ /** All workflow nodes (optional, forwarded to registered editors for port-derived variables) */
18
+ nodes?: WorkflowNode[];
19
+ /** All workflow edges (optional, forwarded to registered editors for port-derived variables) */
20
+ edges?: WorkflowEdge[];
21
+ /** Workflow ID (optional, forwarded to registered editors for template variable API mode) */
22
+ workflowId?: string;
23
+ /** Auth provider (optional, forwarded to registered editors for API requests) */
24
+ authProvider?: AuthProvider;
13
25
  /** Callback when the field value changes */
14
26
  onChange: (value: unknown) => void;
15
27
  }
@@ -16,7 +16,9 @@
16
16
  import type { ConfigSchema, WorkflowNode, WorkflowEdge, AuthProvider } from '../../types/index.js';
17
17
  import type { FieldSchema } from './types.js';
18
18
  import { resolveScopeToKey } from '../../utils/uischema.js';
19
- import FormField from './FormField.svelte';
19
+ // Use the registry-based light field factory so the UISchema renderer (and
20
+ // SchemaForm/ConfigForm above it) never statically pull in CodeMirror.
21
+ import FormField from './FormFieldLight.svelte';
20
22
  import FormFieldset from './FormFieldset.svelte';
21
23
  import Self from './FormUISchemaRenderer.svelte';
22
24
 
@@ -199,7 +199,12 @@
199
199
  try {
200
200
  // Call API if service is configured
201
201
  if (interruptService.isConfigured(fd.api.config)) {
202
- await interruptService.resolveInterrupt(fd.api.config, currentInterrupt.id, value);
202
+ await interruptService.resolveInterrupt(
203
+ fd.api.config,
204
+ currentInterrupt.id,
205
+ value,
206
+ fd.api.authProvider
207
+ );
203
208
  }
204
209
 
205
210
  // Mark as successful - transitions to resolved state
@@ -229,7 +234,11 @@
229
234
  try {
230
235
  // Call API if service is configured
231
236
  if (interruptService.isConfigured(fd.api.config)) {
232
- await interruptService.cancelInterrupt(fd.api.config, currentInterrupt.id);
237
+ await interruptService.cancelInterrupt(
238
+ fd.api.config,
239
+ currentInterrupt.id,
240
+ fd.api.authProvider
241
+ );
233
242
  }
234
243
 
235
244
  // Mark as successful - transitions to cancelled state
@@ -46,19 +46,21 @@
46
46
  import type { NodeStatus } from './pipelineViewUtils.svelte.js';
47
47
  import type { Workflow, WorkflowNode } from '../../types/index.js';
48
48
  import type { EndpointConfig } from '../../config/endpoints.js';
49
+ import type { AuthProvider } from '../../types/auth.js';
49
50
 
50
51
  interface Props {
51
52
  pipelineId: string;
52
53
  workflow: Workflow;
53
54
  endpointConfig: EndpointConfig;
55
+ authProvider?: AuthProvider;
54
56
  refreshTrigger?: number;
55
57
  }
56
58
 
57
- let { pipelineId, workflow, endpointConfig, refreshTrigger = 0 }: Props = $props();
59
+ let { pipelineId, workflow, endpointConfig, authProvider, refreshTrigger = 0 }: Props = $props();
58
60
 
59
61
  // endpointConfig is consumed once to build the API client; it must be stable
60
62
  // svelte-ignore state_referenced_locally
61
- const fetcher = createPipelineDataFetcher(() => pipelineId, endpointConfig);
63
+ const fetcher = createPipelineDataFetcher(() => pipelineId, endpointConfig, authProvider);
62
64
 
63
65
  $effect(() => {
64
66
  if (refreshTrigger <= 0) return;
@@ -1,9 +1,11 @@
1
1
  import type { Workflow } from '../../types/index.js';
2
2
  import type { EndpointConfig } from '../../config/endpoints.js';
3
+ import type { AuthProvider } from '../../types/auth.js';
3
4
  interface Props {
4
5
  pipelineId: string;
5
6
  workflow: Workflow;
6
7
  endpointConfig: EndpointConfig;
8
+ authProvider?: AuthProvider;
7
9
  refreshTrigger?: number;
8
10
  }
9
11
  declare const PipelineKanbanView: import("svelte").Component<Props, {}, "">;