@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.
- package/CHANGELOG.md +33 -0
- package/MIGRATION-2.0.md +160 -3
- package/dist/api/enhanced-client.js +6 -11
- package/dist/components/App.svelte +1 -0
- package/dist/components/ConfigForm.svelte +6 -2
- package/dist/components/PipelineStatus.svelte +6 -1
- package/dist/components/PipelineStatus.svelte.d.ts +3 -0
- package/dist/components/SchemaForm.svelte +4 -2
- package/dist/components/WorkflowEditor.svelte +4 -1
- package/dist/components/WorkflowEditor.svelte.d.ts +3 -0
- package/dist/components/chat/AIChatPanel.svelte +6 -1
- package/dist/components/form/FormAutocomplete.svelte +8 -9
- package/dist/components/form/FormFieldLight.svelte +30 -1
- package/dist/components/form/FormFieldLight.svelte.d.ts +12 -0
- package/dist/components/form/FormUISchemaRenderer.svelte +3 -1
- package/dist/components/interrupt/InterruptBubble.svelte +11 -2
- package/dist/components/playground/PipelineKanbanView.svelte +4 -2
- package/dist/components/playground/PipelineKanbanView.svelte.d.ts +2 -0
- package/dist/components/playground/PipelinePanel.svelte +20 -3
- package/dist/components/playground/PipelinePanel.svelte.d.ts +2 -0
- package/dist/components/playground/PipelineTableView.svelte +4 -2
- package/dist/components/playground/PipelineTableView.svelte.d.ts +2 -0
- package/dist/components/playground/Playground.svelte +76 -25
- package/dist/components/playground/Playground.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundApp.svelte +5 -0
- package/dist/components/playground/PlaygroundApp.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundModal.svelte +5 -0
- package/dist/components/playground/PlaygroundModal.svelte.d.ts +3 -0
- package/dist/components/playground/PlaygroundStudio.svelte +7 -1
- package/dist/components/playground/PlaygroundStudio.svelte.d.ts +3 -0
- package/dist/components/playground/pipelineViewUtils.svelte.d.ts +2 -1
- package/dist/components/playground/pipelineViewUtils.svelte.js +2 -2
- package/dist/config/endpoints.d.ts +23 -0
- package/dist/config/endpoints.js +28 -0
- package/dist/core/index.d.ts +1 -2
- package/dist/core/index.js +2 -6
- package/dist/display/index.d.ts +6 -1
- package/dist/display/index.js +9 -1
- package/dist/editor/index.d.ts +1 -1
- package/dist/editor/index.js +1 -1
- package/dist/form/full.d.ts +2 -1
- package/dist/form/full.js +4 -1
- package/dist/form/index.d.ts +0 -1
- package/dist/form/index.js +3 -2
- package/dist/helpers/workflowEditorHelper.d.ts +4 -2
- package/dist/helpers/workflowEditorHelper.js +4 -3
- package/dist/playground/index.d.ts +2 -2
- package/dist/playground/index.js +2 -2
- package/dist/playground/mount.d.ts +10 -0
- package/dist/playground/mount.js +8 -4
- package/dist/registry/builtinNodeTypes.d.ts +53 -0
- package/dist/registry/builtinNodeTypes.js +67 -0
- package/dist/registry/builtinNodes.d.ts +2 -39
- package/dist/registry/builtinNodes.js +6 -53
- package/dist/services/agentSpecExecutionService.d.ts +0 -2
- package/dist/services/agentSpecExecutionService.js +0 -2
- package/dist/services/apiVariableService.js +12 -26
- package/dist/services/categoriesApi.js +3 -6
- package/dist/services/chatService.d.ts +4 -3
- package/dist/services/chatService.js +13 -18
- package/dist/services/interruptService.d.ts +7 -6
- package/dist/services/interruptService.js +19 -21
- package/dist/services/playgroundService.d.ts +9 -8
- package/dist/services/playgroundService.js +23 -25
- package/dist/services/portConfigApi.js +3 -6
- package/dist/services/settingsService.d.ts +9 -4
- package/dist/services/settingsService.js +23 -12
- package/dist/stores/apiContext.d.ts +11 -0
- package/dist/stores/apiContext.js +15 -0
- package/dist/stores/categoriesStore.svelte.js +0 -1
- package/dist/stores/playgroundStore.svelte.js +0 -2
- package/dist/svelte-app.js +2 -1
- package/dist/types/auth.d.ts +9 -51
- package/dist/types/auth.js +4 -54
- package/dist/types/index.d.ts +4 -2
- package/dist/types/index.js +0 -1
- package/dist/utils/edgeStyling.js +9 -5
- package/dist/utils/fetchWithAuth.d.ts +36 -15
- package/dist/utils/fetchWithAuth.js +53 -23
- package/dist/utils/nodeTypes.js +1 -1
- 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`, `
|
|
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,
|
|
320
|
+
import { Playground, PlaygroundStore } from '@flowdrop/flowdrop/editor';
|
|
216
321
|
|
|
217
322
|
// 2.0
|
|
218
|
-
import { 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,
|
|
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
|
-
//
|
|
63
|
-
|
|
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
|
-
...
|
|
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
|
-
//
|
|
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
|
-
...
|
|
100
|
-
...newAuthHeaders,
|
|
95
|
+
...(await getRequestHeaders(this.config, endpointKey, this.authProvider)),
|
|
101
96
|
...options.headers
|
|
102
97
|
};
|
|
103
98
|
continue; // Retry with new headers
|
|
@@ -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
|
-
|
|
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/
|
|
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
|
-
|
|
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/
|
|
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(
|
|
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 {
|
|
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
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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 {
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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, {}, "">;
|