@w6w/embed 0.2.1 → 0.2.19

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 (185) hide show
  1. package/README.md +22 -5
  2. package/dist/ConfirmModal-Pv2-A_3U.js +186 -0
  3. package/dist/ConfirmModal-Pv2-A_3U.js.map +1 -0
  4. package/dist/{CreateFunctionModal-DRsFx-FB.js → CreateFunctionModal-DScxp_LN.js} +25 -25
  5. package/dist/{CreateFunctionModal-DRsFx-FB.js.map → CreateFunctionModal-DScxp_LN.js.map} +1 -1
  6. package/dist/{DocumentFormModal-BExK1V-B.js → DocumentFormModal-Br4s8wmi.js} +5 -5
  7. package/dist/{DocumentFormModal-BExK1V-B.js.map → DocumentFormModal-Br4s8wmi.js.map} +1 -1
  8. package/dist/ImportSpecModal-Cpzp8ndt.js +251 -0
  9. package/dist/ImportSpecModal-Cpzp8ndt.js.map +1 -0
  10. package/dist/ModelRoutesManager-1Ac5wcas.js +345 -0
  11. package/dist/ModelRoutesManager-1Ac5wcas.js.map +1 -0
  12. package/dist/WorkflowEditor-CmhXHRxi.js +1109 -0
  13. package/dist/WorkflowEditor-CmhXHRxi.js.map +1 -0
  14. package/dist/apps-ItBvnWX3.js +92 -0
  15. package/dist/apps-ItBvnWX3.js.map +1 -0
  16. package/dist/{callables-3mFrMVG_.js → callables-tOlflvbl.js} +11 -11
  17. package/dist/{callables-3mFrMVG_.js.map → callables-tOlflvbl.js.map} +1 -1
  18. package/dist/chrome/ConfirmModal.d.ts +4 -1
  19. package/dist/chrome/DangerZone.d.ts +4 -3
  20. package/dist/chrome/ExecutionProfileHeader.d.ts +3 -3
  21. package/dist/chrome/JsonToggle.d.ts +29 -20
  22. package/dist/chrome/Modal.d.ts +3 -1
  23. package/dist/chrome/RightRail.d.ts +6 -1
  24. package/dist/chrome/VersionHistoryModal.d.ts +2 -0
  25. package/dist/chrome/index.d.ts +1 -0
  26. package/dist/chrome/workspace.d.ts +36 -1
  27. package/dist/coerce-input-DFJ4n_wc.js +150 -0
  28. package/dist/coerce-input-DFJ4n_wc.js.map +1 -0
  29. package/dist/connections-CzsCyIxY.js +119 -0
  30. package/dist/connections-CzsCyIxY.js.map +1 -0
  31. package/dist/credentials-Cn92LGhJ.js +171 -0
  32. package/dist/credentials-Cn92LGhJ.js.map +1 -0
  33. package/dist/data-stores-UeQvwVCa.js +170 -0
  34. package/dist/data-stores-UeQvwVCa.js.map +1 -0
  35. package/dist/document-sources-DNmBojx6.js +169 -0
  36. package/dist/document-sources-DNmBojx6.js.map +1 -0
  37. package/dist/draft/use-workflow-draft.d.ts +2 -0
  38. package/dist/draft.mjs +2 -2
  39. package/dist/editor/BindingBanner.d.ts +13 -0
  40. package/dist/editor/CallableEditorFrame.d.ts +7 -0
  41. package/dist/editor/EndpointCards.d.ts +4 -1
  42. package/dist/editor/PublishControl.d.ts +19 -0
  43. package/dist/editor/PublishTooltip.d.ts +7 -0
  44. package/dist/editor/SetupIncompleteBanner.d.ts +12 -0
  45. package/dist/editor/StartingStateModal.d.ts +14 -0
  46. package/dist/editor/TargetSelector.d.ts +15 -0
  47. package/dist/editor/TargetSelector.types.d.ts +2 -0
  48. package/dist/editor/WorkflowSettingsModal.d.ts +6 -1
  49. package/dist/editor/WorkflowVariablesEditor.d.ts +6 -0
  50. package/dist/editor/definition.d.ts +6 -0
  51. package/dist/editor/json-apply.d.ts +29 -0
  52. package/dist/editor/step-problems-feed.d.ts +5 -0
  53. package/dist/editor/types.d.ts +2 -2
  54. package/dist/editor-apps-DkkC7wOQ.js +152 -0
  55. package/dist/editor-apps-DkkC7wOQ.js.map +1 -0
  56. package/dist/editor-tools-BR27RGto.js +1683 -0
  57. package/dist/editor-tools-BR27RGto.js.map +1 -0
  58. package/dist/editor.mjs +1 -1
  59. package/dist/editors.mjs +855 -650
  60. package/dist/editors.mjs.map +1 -1
  61. package/dist/{endpoints-B2ynbZo-.js → endpoints-DSRo1Lc5.js} +113 -107
  62. package/dist/endpoints-DSRo1Lc5.js.map +1 -0
  63. package/dist/fields-DvS8XZFc.js +21 -0
  64. package/dist/fields-DvS8XZFc.js.map +1 -0
  65. package/dist/forms/ModelBudgetsManager.d.ts +9 -0
  66. package/dist/forms/ModelRoutesManager.d.ts +14 -0
  67. package/dist/forms.d.ts +4 -0
  68. package/dist/forms.mjs +611 -212
  69. package/dist/forms.mjs.map +1 -1
  70. package/dist/{rail-settings-XYGToh00.js → import-bindings-EUtxZ9Ti.js} +90 -24
  71. package/dist/import-bindings-EUtxZ9Ti.js.map +1 -0
  72. package/dist/index.mjs +154 -117
  73. package/dist/index.mjs.map +1 -1
  74. package/dist/lib/binding-problems.d.ts +42 -0
  75. package/dist/lib/code-rail.d.ts +4 -2
  76. package/dist/lib/history-query.d.ts +45 -0
  77. package/dist/lib/import-bindings.d.ts +89 -0
  78. package/dist/lib/index.d.ts +4 -0
  79. package/dist/lib/invoke-error.d.ts +1 -0
  80. package/dist/lib/rail-settings.d.ts +1 -1
  81. package/dist/lib/sdk-snippets.d.ts +1 -1
  82. package/dist/lib/setup-incomplete.d.ts +22 -0
  83. package/dist/lib/starting-data.d.ts +31 -0
  84. package/dist/lib/state-panel.d.ts +29 -0
  85. package/dist/lib/target-fields.d.ts +11 -15
  86. package/dist/lib/trigger-preview.d.ts +1 -0
  87. package/dist/lib/workflow-live-run.d.ts +93 -8
  88. package/dist/lib/workflow-nodes.d.ts +5 -0
  89. package/dist/lib/workflow-validity.d.ts +65 -16
  90. package/dist/lib/workflow-variables.d.ts +1 -1
  91. package/dist/lib/workflow-version.d.ts +2 -0
  92. package/dist/lib.mjs +86 -69
  93. package/dist/lists/ConnectionDependents.d.ts +31 -0
  94. package/dist/lists/ConnectionDetail.d.ts +4 -1
  95. package/dist/lists/ConnectionList.d.ts +4 -1
  96. package/dist/lists/CredentialDetail.d.ts +15 -0
  97. package/dist/lists/CredentialList.d.ts +14 -0
  98. package/dist/lists/DataStoreList.d.ts +17 -0
  99. package/dist/lists/DataStoreView.d.ts +19 -0
  100. package/dist/lists/Logs.d.ts +19 -0
  101. package/dist/lists/ModelCatalog.d.ts +12 -0
  102. package/dist/lists/ModelUsage.d.ts +12 -0
  103. package/dist/lists.d.ts +14 -0
  104. package/dist/lists.mjs +1766 -609
  105. package/dist/lists.mjs.map +1 -1
  106. package/dist/models-bAayQPJ_.js +270 -0
  107. package/dist/models-bAayQPJ_.js.map +1 -0
  108. package/dist/{project-context-BiCjv_E3.js → project-context-Tvp-La7A.js} +3 -3
  109. package/dist/{project-context-BiCjv_E3.js.map → project-context-Tvp-La7A.js.map} +1 -1
  110. package/dist/rail/ConnectionsTool.d.ts +2 -0
  111. package/dist/rail/HistoryTool.d.ts +2 -0
  112. package/dist/rail/StartingStateTool.d.ts +2 -0
  113. package/dist/rail/settings-sections.d.ts +4 -1
  114. package/dist/rail.mjs +4 -4
  115. package/dist/repos/agents-studio-agents.d.ts +52 -0
  116. package/dist/repos/agents-studio-assets.d.ts +68 -0
  117. package/dist/repos/connections.d.ts +30 -12
  118. package/dist/repos/constants.d.ts +12 -0
  119. package/dist/repos/credentials.d.ts +83 -0
  120. package/dist/repos/data-stores.d.ts +84 -0
  121. package/dist/repos/endpoints.d.ts +9 -3
  122. package/dist/repos/fields.d.ts +34 -0
  123. package/dist/repos/functions.d.ts +7 -5
  124. package/dist/repos/history.d.ts +9 -0
  125. package/dist/repos/index.d.ts +7 -0
  126. package/dist/repos/models.d.ts +289 -0
  127. package/dist/repos/spec-export.d.ts +3 -3
  128. package/dist/repos/spec-import.d.ts +30 -1
  129. package/dist/repos/step-tests.d.ts +2 -0
  130. package/dist/repos/webhook-listen.d.ts +35 -0
  131. package/dist/repos/workflows.d.ts +105 -2
  132. package/dist/repos.mjs +655 -176
  133. package/dist/repos.mjs.map +1 -1
  134. package/dist/setup-incomplete-BHs3Lpfy.js +199 -0
  135. package/dist/setup-incomplete-BHs3Lpfy.js.map +1 -0
  136. package/dist/{slug-C4ktDPdy.js → slug-BVdgiP_L.js} +64 -60
  137. package/dist/slug-BVdgiP_L.js.map +1 -0
  138. package/dist/{spec-export-Cf3VQSQS.js → spec-export-DGy5ijps.js} +73 -60
  139. package/dist/spec-export-DGy5ijps.js.map +1 -0
  140. package/dist/spec-import-SWOonsNr.js +116 -0
  141. package/dist/spec-import-SWOonsNr.js.map +1 -0
  142. package/dist/{step-tests-CivICmTq.js → step-tests-B4E4W3ly.js} +8 -7
  143. package/dist/step-tests-B4E4W3ly.js.map +1 -0
  144. package/dist/theme-context-E2ZhlXDX.js +6 -0
  145. package/dist/theme-context-E2ZhlXDX.js.map +1 -0
  146. package/dist/theme-context.d.ts +2 -0
  147. package/dist/{use-callable-draft-zHLpcr-b.js → use-callable-draft-DCauHt5o.js} +23 -23
  148. package/dist/{use-callable-draft-zHLpcr-b.js.map → use-callable-draft-DCauHt5o.js.map} +1 -1
  149. package/dist/use-workflow-draft-l3P5KZzw.js +338 -0
  150. package/dist/use-workflow-draft-l3P5KZzw.js.map +1 -0
  151. package/dist/{workflow-blank-DyL3_RUA.js → workflow-blank-DFpGObrn.js} +6 -6
  152. package/dist/{workflow-blank-DyL3_RUA.js.map → workflow-blank-DFpGObrn.js.map} +1 -1
  153. package/dist/workflows-BZN4Hyz1.js +623 -0
  154. package/dist/workflows-BZN4Hyz1.js.map +1 -0
  155. package/package.json +3 -2
  156. package/src/styles.css +155 -7
  157. package/dist/ConfirmModal-RLbZT5_k.js +0 -181
  158. package/dist/ConfirmModal-RLbZT5_k.js.map +0 -1
  159. package/dist/ImportSpecModal-BDQIf6rg.js +0 -136
  160. package/dist/ImportSpecModal-BDQIf6rg.js.map +0 -1
  161. package/dist/WorkflowEditor-DlbVv6Fs.js +0 -854
  162. package/dist/WorkflowEditor-DlbVv6Fs.js.map +0 -1
  163. package/dist/apps-1FNUwbGv.js +0 -77
  164. package/dist/apps-1FNUwbGv.js.map +0 -1
  165. package/dist/coerce-input-BicYr7nc.js +0 -139
  166. package/dist/coerce-input-BicYr7nc.js.map +0 -1
  167. package/dist/connections-CjjYeRqb.js +0 -78
  168. package/dist/connections-CjjYeRqb.js.map +0 -1
  169. package/dist/document-sources-C0grrtdq.js +0 -86
  170. package/dist/document-sources-C0grrtdq.js.map +0 -1
  171. package/dist/editor-apps-BdenSV1o.js +0 -95
  172. package/dist/editor-apps-BdenSV1o.js.map +0 -1
  173. package/dist/editor-tools-RxmY5iyi.js +0 -1279
  174. package/dist/editor-tools-RxmY5iyi.js.map +0 -1
  175. package/dist/endpoints-B2ynbZo-.js.map +0 -1
  176. package/dist/rail-settings-XYGToh00.js.map +0 -1
  177. package/dist/slug-C4ktDPdy.js.map +0 -1
  178. package/dist/spec-export-Cf3VQSQS.js.map +0 -1
  179. package/dist/spec-import-CjmxyZDR.js +0 -465
  180. package/dist/spec-import-CjmxyZDR.js.map +0 -1
  181. package/dist/step-tests-CivICmTq.js.map +0 -1
  182. package/dist/trigger-preview-VPkrryDl.js +0 -120
  183. package/dist/trigger-preview-VPkrryDl.js.map +0 -1
  184. package/dist/use-workflow-draft-DzAyUeA6.js +0 -316
  185. package/dist/use-workflow-draft-DzAyUeA6.js.map +0 -1
@@ -1,6 +1,9 @@
1
+ import { ReactNode } from 'react';
1
2
  interface ConfirmModalProps {
2
3
  title: string;
3
4
  message: string;
5
+ /** Optional content rendered under the message (e.g. a list of impacted items). */
6
+ children?: ReactNode;
4
7
  /** Fired when the user confirms. The caller clears its pending state via onClose. */
5
8
  onConfirm: () => void;
6
9
  /** Fired on Cancel, Esc, or outside-click — dismisses without confirming. */
@@ -16,5 +19,5 @@ interface ConfirmModalProps {
16
19
  * confirmation prompt for destructive actions: Confirm fires `onConfirm`;
17
20
  * Cancel/Esc/outside-click fires `onClose` only (no confirmation).
18
21
  */
19
- export declare function ConfirmModal({ title, message, onConfirm, onClose, confirmLabel, cancelLabel, destructive, }: ConfirmModalProps): import("react").JSX.Element;
22
+ export declare function ConfirmModal({ title, message, children, onConfirm, onClose, confirmLabel, cancelLabel, destructive, }: ConfirmModalProps): import("react").JSX.Element;
20
23
  export {};
@@ -1,8 +1,9 @@
1
1
  export interface DangerZoneProps {
2
- /** Whether the resource is archived yet. `true` renders Delete; `false`
3
- * renders Archive. Every kind has an archive-before-delete step as of
4
- * T4.1.1 (Function/Endpoint newly, Workflow already did). */
2
+ /** Archived resources offer Delete; other resources also offer Archive. */
5
3
  archived: boolean;
4
+ /** Offer Delete before archiving when the caller handles both lifecycle operations. */
5
+ allowDirectDelete?: boolean;
6
+ pending?: boolean;
6
7
  /** Accessible name for the Delete icon button — `title`/`aria-label` only
7
8
  * (`IconButton.tsx`), e.g. "Delete this function". */
8
9
  deleteLabel: string;
@@ -57,11 +57,11 @@ export interface ExecutionProfileHeaderProps {
57
57
  * `?edit=`; `CallableEditorChrome` navigates to the kind's listing). */
58
58
  onBack: () => void;
59
59
  /** The back control's visible text — host-owned copy (`"← Workflows"`,
60
- * `descriptor.editor.backLabel`). */
61
- backLabel: string;
60
+ * `descriptor.editor.backLabel`). `null`: no back control is rendered. */
61
+ backLabel: string | null;
62
62
  /** Editable (Workflow) or read-only (Function/Endpoint) title. */
63
63
  title: ExecutionProfileTitle;
64
- /** Rendered immediately after a read-only title — the `incomplete` badge. */
64
+ /** Rendered immediately after the title, including an editable workflow name. */
65
65
  titleAdornment?: ReactNode;
66
66
  /** The host's action row (buttons only; this component owns the wrapper). */
67
67
  actions: ReactNode;
@@ -1,4 +1,19 @@
1
- export type JsonToggleMode = "synced" | "disconnected";
1
+ /**
2
+ * `apply`: the dialog edits its own copy of the text and hands it to the host only on Apply (the
3
+ * workflow editor, whose canvas re-reads it). `disconnected`: the host owns the text and saves it.
4
+ */
5
+ export type JsonToggleMode = "apply" | "disconnected";
6
+ /** What `prepareApply` makes of the dialog's text: the text to apply, or why it can't be. */
7
+ export type JsonApplyCheck = {
8
+ ok: true;
9
+ /** The text `onApply` receives — the edited text with any protected field put back. */
10
+ text: string;
11
+ /** Top-level fields whose loaded value was restored; listed under the editor. */
12
+ restored: string[];
13
+ } | {
14
+ ok: false;
15
+ error: string;
16
+ };
2
17
  /** The header icon button: `IconButton` with the set's `json` glyph — the
3
18
  * curly-brace icon, distinct from the `code` `</>` "Call from code" icon
4
19
  * beside it, so the two stop reading as the same button. The local
@@ -14,17 +29,15 @@ export interface JsonToggleProps {
14
29
  /** Modal title. */
15
30
  title: string;
16
31
  mode: JsonToggleMode;
17
- /** Parent-owned text; the component keeps NO copy of it. */
32
+ /** disconnected: parent-owned text, the component keeps NO copy of it. apply: the text the
33
+ * dialog starts from each time it opens. */
18
34
  value: string;
19
- /** Every JsonEditor change, both modes. */
20
- onChange: (text: string) => void;
21
- /** JsonEditor's, error ?? null. */
22
- onValidityChange?: (v: {
23
- valid: boolean;
24
- error: string | null;
25
- }) => void;
26
- /** When non-null: "Invalid JSON — {invalidReason}" (Workflow's existing line). */
27
- invalidReason?: string | null;
35
+ /** disconnected only: every JsonEditor change. */
36
+ onChange?: (text: string) => void;
37
+ /** apply only: validates the dialog's text on every edit; Apply is enabled only on `ok`. */
38
+ prepareApply?: (text: string) => JsonApplyCheck;
39
+ /** apply only: the checked text, on Apply. */
40
+ onApply?: (text: string) => void;
28
41
  /** Evaluated on `value` every render; non-null → shown in
29
42
  * <p className="muted small" data-testid="json-toggle-reason">. */
30
43
  guard?: (text: string) => string | null;
@@ -38,14 +51,10 @@ export interface JsonToggleProps {
38
51
  editorLabel: string;
39
52
  }
40
53
  /**
41
- * The JSON⇄editor toggle's chrome — the header icon button's dialog, extracted
42
- * verbatim from `WorkflowsPage.tsx`'s raw-JSON modal (T2.1.1 D-2) so a second
43
- * host can reuse it in `mode="disconnected"` (T2.1.2). Wraps `@w6w/ui`'s
44
- * `JsonEditor` and studio's own `Modal` (not `@w6w/ui`'s) — both existing
45
- * JSON-toggle-shaped precedents in this repo use studio's `Modal`.
46
- *
47
- * The component holds NO copy of `value`: every render shows exactly what the
48
- * parent hands it, which is what keeps a reopened dialog free of a stale
49
- * snapshot from the previous time it was open.
54
+ * The JSON⇄editor toggle's chrome — the header icon button's dialog, extracted from
55
+ * `WorkflowsPage.tsx`'s raw-JSON modal (T2.1.1 D-2) and reused by the Function and Endpoint
56
+ * editors in `mode="disconnected"` (T2.1.2). Wraps `@w6w/ui`'s `JsonEditor` and studio's own
57
+ * `Modal`. The editor fills the dialog and scrolls inside itself (`.modal-json`), so the title,
58
+ * the description and the footer buttons stay in view on a long definition.
50
59
  */
51
60
  export declare function JsonToggle(props: JsonToggleProps): JSX.Element | null;
@@ -10,11 +10,13 @@ interface ModalProps {
10
10
  * the title and this node share one `.modal-head` row; absent, the title
11
11
  * renders as a direct child exactly as before. */
12
12
  headerRight?: React.ReactNode;
13
+ /** Extra class on the `<dialog>` (e.g. `modal-json`, the fill-and-scroll JSON layout). */
14
+ className?: string;
13
15
  }
14
16
  /**
15
17
  * Small dialog modal. Built on the native <dialog> element so it gets focus
16
18
  * trapping, Esc-dismiss, and accessibility semantics for free. A button
17
19
  * positioned over the backdrop catches outside-clicks to close.
18
20
  */
19
- export declare function Modal({ title, onClose, children, wide, xl, headerRight, }: ModalProps): import("react").JSX.Element;
21
+ export declare function Modal({ title, onClose, children, wide, xl, headerRight, className, }: ModalProps): import("react").JSX.Element;
20
22
  export {};
@@ -12,9 +12,14 @@ export interface RailTool {
12
12
  isAvailable(ctx: WorkspaceCallable): boolean;
13
13
  /** Panel renders its own heading when it includes section actions. */
14
14
  rendersHeading?: boolean;
15
- Panel: ComponentType<{
15
+ /** Absent for an action tool: one with `onActivate` opens nothing in the rail. */
16
+ Panel?: ComponentType<{
16
17
  ctx: WorkspaceCallable;
17
18
  }>;
19
+ /** An action tool: the strip button calls this instead of toggling a panel (e.g. a modal). */
20
+ onActivate?(ctx: WorkspaceCallable): void;
21
+ /** A dot on the strip button: the tool has something set. */
22
+ hasIndicator?(ctx: WorkspaceCallable): boolean;
18
23
  }
19
24
  /** `storageKey === null`: no key to persist under yet (pin 12) — the strip renders closed and
20
25
  * nothing is written to localStorage. No available tool ⇒ no rail element at all (C/D-C3). */
@@ -35,4 +35,6 @@ export declare function VersionHistoryModal(props: {
35
35
  id: string;
36
36
  versionNumber: number;
37
37
  onClose: () => void;
38
+ /** Editor hosts serialize draft saves before restoring, then refresh their buffer. */
39
+ onRestore?: (versionNumber: number) => Promise<void>;
38
40
  }): import("react").JSX.Element;
@@ -33,6 +33,7 @@ export { codeTool } from '../rail/CodeTool.tsx';
33
33
  export { ErrorHandlerSection, errorHandlingTool } from '../rail/ErrorHandlingTool.tsx';
34
34
  export type { ErrorHandlerKind, ErrorHandlerSectionProps } from '../rail/ErrorHandlingTool.tsx';
35
35
  export { ProjectExpressionScope, useProjectExpressionOptions } from '../rail/ExpressionScope.tsx';
36
+ export { startingStateTool } from '../rail/StartingStateTool.tsx';
36
37
  export { editorRailTools } from '../rail/editor-tools.ts';
37
38
  export { TargetSelector } from '../editor/TargetSelector.tsx';
38
39
  export type { TargetKind, TargetSelectorProps, TargetValue, } from '../editor/TargetSelector.types.ts';
@@ -1,4 +1,5 @@
1
- import { CallablePolicy, SnippetInput, TriggerPreview } from '@w6w/embed/lib';
1
+ import { CallablePolicy, SnippetInput, TriggerPreview, WorkflowVariableRow } from '@w6w/embed/lib';
2
+ import { WorkflowConnectionResources } from '@w6w/ui/flow';
2
3
  import { ReactNode } from 'react';
3
4
  /**
4
5
  * T2.1.2: widened to a discriminated union, one arm per kind — every new
@@ -46,10 +47,26 @@ export type WorkspaceCallable = {
46
47
  onPolicyChange?: (policy: CallablePolicy) => void;
47
48
  } | {
48
49
  kind: "workflow";
50
+ connectionResources?: WorkflowConnectionResources;
49
51
  id: string;
50
52
  label?: string;
51
53
  key?: string;
52
54
  triggers?: TriggerPreview[];
55
+ /** Stable editor-owned actions serialize pending draft saves and refresh its buffer. */
56
+ onRestoreVersion?: (versionNumber: number) => Promise<void>;
57
+ /** Whether the editor buffer matches the published snapshot; absent while loading. */
58
+ definitionStatus?: "published" | "draft" | "unpublished";
59
+ /** Use the editor's save/publish guard from the sidebar too. Must be stable. */
60
+ onPublish?: () => Promise<void>;
61
+ publishDisabled?: boolean;
62
+ authoringSettings?: {
63
+ autoSave: boolean;
64
+ savePosition: boolean;
65
+ };
66
+ onAuthoringSettingChange?: (key: "autoSave" | "savePosition", value: boolean) => void;
67
+ variables?: WorkflowVariableRow[];
68
+ onVariablesChange?: (variables: WorkflowVariableRow[]) => void;
69
+ onOpenHistory?: () => void;
53
70
  /**
54
71
  * The workflow's run-level error policy, and the writer that applies it
55
72
  * (core Workflow RFC — *Amendment — 2026-08-21: the run-level error
@@ -68,10 +85,28 @@ export type WorkspaceCallable = {
68
85
  */
69
86
  policy?: CallablePolicy;
70
87
  onPolicyChange?: (policy: CallablePolicy) => void;
88
+ /** `Workflow.initialState` is a non-empty object: the rail State tool's dot. */
89
+ hasStartingState?: boolean;
90
+ /** `Workflow.initialState` as the editor holds it: the State panel's starting state preview. */
91
+ startingState?: Record<string, unknown>;
92
+ /**
93
+ * Opens the canvas editor's starting state editor; the rail State tool shows only when it
94
+ * is set. Same ⚠️ as `onPolicyChange`: it MUST be referentially stable.
95
+ */
96
+ onOpenStartingState?: () => void;
97
+ /**
98
+ * Opens one of this workflow's runs on the canvas (the History "Open run" path): the State
99
+ * panel's link to the run its current state comes from. Same ⚠️: referentially stable.
100
+ */
101
+ onOpenRun?: (runId: string) => void;
71
102
  } | {
72
103
  kind: "connection";
73
104
  id: string;
74
105
  label?: string;
106
+ /** Set by the connection ACTION page: the Code tool needs an action to show a snippet. */
107
+ action?: string;
108
+ /** Declared param keys of `action` (plain data — the registry keys on JSON). */
109
+ params?: readonly SnippetInput[];
75
110
  } | null;
76
111
  /** Derived from {@link WorkspaceCallable}, never redeclared — the arm a
77
112
  * `RailTool.isAvailable`/route wrapper narrows on. */
@@ -0,0 +1,150 @@
1
+ import { effectiveParam as y, matchesParamCondition as k } from "@w6w/expr";
2
+ function m(n) {
3
+ return n.kind === "action" ? "" : n.kind === "endpoint" ? n.endpoint : n.kind === "function" ? n.function : n.workflow;
4
+ }
5
+ function N(n) {
6
+ return n.kind === "action" ? !!(n.uses.app && n.uses.action) : !!m(n);
7
+ }
8
+ function j(n) {
9
+ return n ? n.kind === "function" ? { kind: "function", function: n.function } : n.kind === "workflow" ? { kind: "workflow", workflow: n.workflow } : { kind: "action", uses: n.uses, with: n.with } : { kind: "action", uses: { app: "", action: "", connection: null }, with: {} };
10
+ }
11
+ function b(n) {
12
+ return n.kind === "action" ? { uses: n.uses, with: n.with ?? {} } : { ...n, with: {} };
13
+ }
14
+ function P(n, e) {
15
+ const t = b(e);
16
+ if (!(n != null && n.outputMap)) return t;
17
+ const u = n.kind ?? "action";
18
+ let i = !1;
19
+ if (u === "action" && e.kind === "action") {
20
+ const o = n;
21
+ i = o.uses.app === e.uses.app && o.uses.action === e.uses.action;
22
+ } else u === "function" && e.kind === "function" ? i = n.function === e.function : u === "workflow" && e.kind === "workflow" && (i = n.workflow === e.workflow);
23
+ return i ? { ...t, outputMap: n.outputMap } : t;
24
+ }
25
+ function A(n) {
26
+ return n.map((e) => {
27
+ const t = {
28
+ key: e.key,
29
+ label: e.label ?? e.key,
30
+ type: e.type ?? "string",
31
+ required: e.required,
32
+ default: e.default
33
+ };
34
+ return e.showIf !== void 0 && (t.showIf = e.showIf), e.when !== void 0 && (t.when = e.when), t;
35
+ });
36
+ }
37
+ function M(n, e) {
38
+ var r, s;
39
+ const t = (n == null ? void 0 : n.nodes) ?? (n == null ? void 0 : n.steps), u = Array.isArray(t) ? t : [], i = /* @__PURE__ */ new Set(), o = [];
40
+ for (const f of u) {
41
+ const l = (r = f == null ? void 0 : f.uses) == null ? void 0 : r.app;
42
+ if (typeof l != "string" || !e.isTriggerApp(l)) continue;
43
+ const h = e.asFieldDefs((s = f == null ? void 0 : f.with) == null ? void 0 : s.fields);
44
+ for (const d of h) {
45
+ const c = d.key;
46
+ typeof c != "string" || c.trim() === "" || i.has(c) || (i.add(c), o.push({ key: c, label: c, type: d.type ?? "string", required: d.required }));
47
+ }
48
+ }
49
+ return o;
50
+ }
51
+ const w = ["string", "text", "number", "boolean", "json", "secret"];
52
+ function R(n) {
53
+ return n.rows.length === 0 && !n.touched;
54
+ }
55
+ function F(n) {
56
+ return w.includes(n) ? n : "string";
57
+ }
58
+ function x(n, e) {
59
+ const t = new Set(n.map((i) => i.key)), u = [];
60
+ for (const i of e) {
61
+ const o = i.key;
62
+ typeof o != "string" || o.trim() === "" || t.has(o) || (t.add(o), u.push({
63
+ key: o,
64
+ label: i.label ?? o,
65
+ type: F(i.type),
66
+ required: !!i.required
67
+ }));
68
+ }
69
+ return u.length === 0 ? n : [...n, ...u];
70
+ }
71
+ function q(n, e) {
72
+ const t = n.showIf;
73
+ return t ? k(t, e) : !0;
74
+ }
75
+ function I(n) {
76
+ return n == null ? !1 : typeof n == "string" ? n.trim() !== "" : !0;
77
+ }
78
+ function a(n, e, t) {
79
+ const u = new Set(n.map((r) => r.key)), i = (r) => {
80
+ var s;
81
+ return (t == null ? void 0 : t[r]) !== void 0 ? t[r] : (s = e.find((f) => f.key === r)) == null ? void 0 : s.default;
82
+ }, o = [];
83
+ for (const r of e) {
84
+ if (!y(r, i).required) continue;
85
+ const s = r.key;
86
+ typeof s != "string" || s.trim() === "" || u.has(s) || o.includes(s) || q(r, i) && (I(r.default) || o.push(s));
87
+ }
88
+ return o;
89
+ }
90
+ function B(n, e) {
91
+ if (!(e.emptyMeansPassthrough && n.length === 0))
92
+ return n;
93
+ }
94
+ function S(n) {
95
+ return n == null ? !1 : typeof n == "string" ? n.trim() !== "" : typeof n == "object" && "type" in n && n.type === "expr" ? !0 : typeof n == "object";
96
+ }
97
+ function p(n) {
98
+ const e = [];
99
+ for (const t of Object.keys(n))
100
+ S(n[t]) && e.push({ key: t, label: t, type: "string" });
101
+ return e;
102
+ }
103
+ function g(n) {
104
+ const { target: e, rows: t, fields: u } = n;
105
+ return e.kind === "action" ? e.with === void 0 ? [] : a(p(e.with), u, e.with) : t.length === 0 ? [] : a(t, u);
106
+ }
107
+ function D(n) {
108
+ return n.impl ? a(
109
+ p(n.impl.with ?? {}),
110
+ n.fields,
111
+ n.impl.with ?? {}
112
+ ) : n.fields.filter((e) => e.required).map((e) => e.key);
113
+ }
114
+ function E(n, e) {
115
+ if (e !== "")
116
+ switch (n) {
117
+ case "number": {
118
+ const t = Number(e);
119
+ return Number.isNaN(t) ? e : t;
120
+ }
121
+ case "boolean":
122
+ return e === "true";
123
+ case "json":
124
+ try {
125
+ return JSON.parse(e);
126
+ } catch {
127
+ return e;
128
+ }
129
+ default:
130
+ return e;
131
+ }
132
+ }
133
+ export {
134
+ w as I,
135
+ B as a,
136
+ m as b,
137
+ E as c,
138
+ b as d,
139
+ D as e,
140
+ M as f,
141
+ a as g,
142
+ P as h,
143
+ j as i,
144
+ x as m,
145
+ A as p,
146
+ R as s,
147
+ N as t,
148
+ g as u
149
+ };
150
+ //# sourceMappingURL=coerce-input-DFJ4n_wc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coerce-input-DFJ4n_wc.js","sources":["../src/lib/target-fields.ts","../src/lib/input-seeding.ts","../src/lib/input-coverage.ts","../src/lib/coerce-input.ts"],"sourcesContent":["/**\n * Pure helpers shared by `TargetSelector`'s three arms (rfcs/endpoint.md\n * :339-347 — `EndpointTarget = CallableRef | ActionTarget`) and by\n * `EndpointsPage`'s save gate.\n *\n * Pure and testable by design, mirroring `workflow-validity.ts`'s shape:\n * `@w6w/ui`'s `package.json` `exports[\".\"]` resolves to raw `./src/index.ts`,\n * which re-exports `.tsx` files, so `node --test` throws\n * `ERR_UNKNOWN_FILE_EXTENSION` the moment anything here imports `@w6w/ui` or\n * `@w6w/ui/flow` — even type-only. So this module declares its own local\n * structural (`*Like`) types instead of importing the real ones from\n * `../api/types.ts`, and `isTriggerApp`/`asFieldDefs` (the workflow arm's only\n * dependency on `@w6w/ui/flow`) are **caller-injected** — `TargetSelector.tsx`\n * (unaffected by the JSX constraint) imports the real ones and passes them in.\n */\n\nimport type { ParamWhen } from \"@w6w/expr\";\n\n/** The four arms `EndpointTarget` can take; a Function's `impl` takes the\n * first three (D-8) — `\"endpoint\"` is alias-only, never legal for `Fn.impl`. */\nexport type TargetKind = \"action\" | \"function\" | \"workflow\" | \"endpoint\";\n\n/** The `action` arm — same `{ uses, with }` shape a Function's `impl` carries. */\nexport interface ActionTargetLike {\n kind: \"action\";\n uses: { app: string; action: string; connection?: string | null };\n with?: Record<string, unknown>;\n}\n\n/** The `function`/`workflow` arms — a bare ref, one hop to a CallableRef. */\nexport type CallableTargetLike =\n | { kind: \"function\"; function: string }\n | { kind: \"workflow\"; workflow: string };\n\n/** The `endpoint` arm — a bare ref to another Endpoint. Alias-only (plan.md\n * §2a): legal for `AliasDef.target`, never for an Endpoint's own `target`\n * (the server refuses it — `admin/endpoints.ts`'s `validateDefinition`). */\nexport interface EndpointRefTargetLike {\n kind: \"endpoint\";\n endpoint: string;\n}\n\n/** The full local mirror of `EndpointTarget` this module operates on. */\nexport type TargetLike = ActionTargetLike | CallableTargetLike | EndpointRefTargetLike;\n\n/**\n * The action arm of a Function's `impl` — today's `FunctionImplLike` shape,\n * plus the two fields D-8 adds: `kind?: \"action\"` (absent means \"action\",\n * unchanged for every Function stored before the union existed) and\n * `outputMap?` (mirrors the action arm's own adapter-out pass, already on\n * `FnActionImpl`/`FunctionActionImpl`).\n */\nexport interface ActionImplLike {\n kind?: \"action\";\n uses: { app: string; action: string; connection?: string | null };\n with?: Record<string, unknown>;\n outputMap?: Record<string, unknown>;\n}\n\n/**\n * A Function's `impl` (D-8, `rfcs/function.md` as amended by TC2) — bound to\n * one app Action, or to another Function/Workflow via `CallableTargetLike`\n * (reused verbatim, never a fourth local mirror), intersected with the same\n * `with`/`outputMap` adapter pair the action arm carries — field-for-field\n * `FnCallableImpl = CallableRef & {with?; outputMap?}` (TC2's pinned type).\n */\nexport type FunctionImplLike =\n | ActionImplLike\n | (CallableTargetLike & { with?: Record<string, unknown>; outputMap?: Record<string, unknown> });\n\n/** A declared action/function param, just enough of it for the projector. */\nexport interface ParamLike {\n key: string;\n label?: string;\n type?: string;\n required?: boolean;\n default?: unknown;\n showIf?: ShowIfPredicate;\n when?: ParamWhen[];\n}\n\n/** Visibility predicate — mirroring ActionParam.showIf from @w6w/ui. */\nexport interface ShowIfPredicate {\n field: string;\n equals?: unknown;\n in?: unknown[];\n notIn?: unknown[];\n truthy?: boolean;\n}\n\n/** One field of a manual/webhook trigger's `with.fields` (`@w6w/ui/flow`'s `TriggerFieldDef`). */\nexport interface TriggerFieldDefLike {\n key?: string;\n type?: string;\n default?: unknown;\n required?: boolean;\n}\n\n/** A workflow graph step, just enough of it for the trigger-field union (A6). */\nexport interface WorkflowStepLike {\n uses?: { app?: string };\n with?: Record<string, unknown>;\n}\n\n/** A workflow definition, just enough of it for the trigger-field union. */\nexport interface WorkflowLike {\n nodes?: unknown;\n steps?: unknown;\n}\n\n/** Everything `fieldsFromWorkflow` needs from `@w6w/ui/flow` but cannot import itself. */\nexport interface WorkflowFieldCtx {\n /** `@w6w/ui/flow`'s `isTriggerApp`, injected by the JSX caller. */\n isTriggerApp: (app: string) => boolean;\n /** `@w6w/ui/flow`'s `asFieldDefs`, injected by the JSX caller. */\n asFieldDefs: (fields: unknown) => TriggerFieldDefLike[];\n}\n\n/** One field of the normalized list `TargetSelector` resolves to (A5). */\nexport interface TargetField {\n key: string;\n label: string;\n type: string;\n required?: boolean;\n default?: unknown;\n showIf?: ShowIfPredicate;\n when?: ParamWhen[];\n}\n\n/** One row of an input-contract list (`FunctionInput`/`EndpointInput`'s common shape). */\nexport interface InputRowLike {\n key: string;\n label: string;\n type: string;\n required?: boolean;\n}\n\n/** The concrete ref (`fn_…` / `wf_…` / `ep_…`) a CallableRef/endpoint target\n * currently points at, `\"\"` for `action`. */\nexport function targetRef(target: TargetLike): string {\n if (target.kind === \"action\") return \"\";\n if (target.kind === \"endpoint\") return target.endpoint;\n return target.kind === \"function\" ? target.function : target.workflow;\n}\n\n/** Is the target fully chosen? An action needs both halves of its `uses` pair (A9). */\nexport function targetIsBound(target: TargetLike): boolean {\n if (target.kind === \"action\") return Boolean(target.uses.app && target.uses.action);\n return Boolean(targetRef(target));\n}\n\n/**\n * Adapt a Function's `impl` into the shape `TargetSelector` consumes (D-8):\n * an action impl to the `action` arm exactly as before; a CallableRef impl maps\n * its `kind`/`function`|`workflow` across UNCHANGED — deliberately dropping\n * `with`/`outputMap`, which `TargetLike`'s CallableRef arm has no slot for (they\n * survive on `draft.impl` itself; `targetToImpl` restores a default `with` on\n * the way back, so `implToTarget(targetToImpl(x))` round-trips `x`). An\n * absent impl still yields the empty action target.\n */\nexport function implToTarget(\n impl: FunctionImplLike | undefined,\n): ActionTargetLike | CallableTargetLike {\n // Draft functions have no impl yet; return an empty target\n if (!impl) {\n return { kind: \"action\", uses: { app: \"\", action: \"\", connection: null }, with: {} };\n }\n if (impl.kind === \"function\") return { kind: \"function\", function: impl.function };\n if (impl.kind === \"workflow\") return { kind: \"workflow\", workflow: impl.workflow };\n return { kind: \"action\", uses: impl.uses, with: impl.with };\n}\n\n/**\n * Inverse of {@link implToTarget}, over the widened D-8 domain. Never yields\n * `with: undefined` on EITHER arm — A10: `invoke-function.ts`'s\n * `resolveWith(impl.with, …)` call is unconditional and shared by both arms\n * (the CallableRef arm has its own `with` adapter pass onto the callee's inputs,\n * unlike `uncoveredForEndpoint`'s P3), so an unmapped `with` must still be\n * `{}`, not absent, on a CallableRef impl too.\n */\nexport function targetToImpl(target: ActionTargetLike | CallableTargetLike): FunctionImplLike {\n if (target.kind === \"action\") {\n return { uses: target.uses, with: target.with ?? {} };\n }\n return { ...target, with: {} };\n}\n\n/**\n * The `impl` a re-pick produces. `outputMap` adapts ONE binding's vendor response, so it survives\n * only while the binding identity is unchanged: the same `uses.app` + `uses.action` (action arm),\n * or the same callable kind + id (ref arm). Connection and `with` edits keep it; a different\n * action or callee drops it (rfcs/function.md: switching provider replaces `impl` wholesale).\n */\nexport function implAfterRebind(\n prev: FunctionImplLike | undefined,\n target: ActionTargetLike | CallableTargetLike,\n): FunctionImplLike {\n const next = targetToImpl(target);\n if (!prev?.outputMap) return next;\n const prevKind = prev.kind ?? \"action\";\n let same = false;\n if (prevKind === \"action\" && target.kind === \"action\") {\n const p = prev as ActionImplLike;\n same = p.uses.app === target.uses.app && p.uses.action === target.uses.action;\n } else if (prevKind === \"function\" && target.kind === \"function\") {\n same = (prev as { function: string }).function === target.function;\n } else if (prevKind === \"workflow\" && target.kind === \"workflow\") {\n same = (prev as { workflow: string }).workflow === target.workflow;\n }\n return same ? { ...next, outputMap: prev.outputMap } : next;\n}\n\n/** Project a list of action/function params into the normalized `TargetField[]` (A5). */\nexport function paramsToFields(params: ParamLike[]): TargetField[] {\n return params.map((p) => {\n const field: TargetField = {\n key: p.key,\n label: p.label ?? p.key,\n type: p.type ?? \"string\",\n required: p.required,\n default: p.default,\n };\n if (p.showIf !== undefined) {\n field.showIf = p.showIf;\n }\n if (p.when !== undefined) {\n field.when = p.when;\n }\n return field;\n });\n}\n\n/**\n * A6: project every manual/webhook-trigger step's `with.fields` from a raw\n * workflow graph into the union of `TargetField`s, keyed by `key`, first\n * occurrence wins, order stable (planner D-2: the server broadcasts one\n * `input` object to every trigger identically). A webhook/scheduler step that\n * declares `methods`/`auth` but no `fields` contributes nothing — by reading\n * `with.fields`, not a special case. Unnamed/blank keys are skipped. `default`\n * is not carried for this arm (A5). A missing/garbage graph, or one whose\n * `isTriggerApp` predicate matches nothing, yields `[]` — never a throw.\n */\nexport function fieldsFromWorkflow(\n workflow: WorkflowLike | null | undefined,\n ctx: WorkflowFieldCtx,\n): TargetField[] {\n const rawNodes = workflow?.nodes ?? workflow?.steps;\n const steps = Array.isArray(rawNodes) ? (rawNodes as WorkflowStepLike[]) : [];\n const seen = new Set<string>();\n const out: TargetField[] = [];\n for (const step of steps) {\n const app = step?.uses?.app;\n if (typeof app !== \"string\" || !ctx.isTriggerApp(app)) continue;\n const defs = ctx.asFieldDefs(step?.with?.fields);\n for (const def of defs) {\n const key = def.key;\n if (typeof key !== \"string\" || key.trim() === \"\" || seen.has(key)) continue;\n seen.add(key);\n out.push({ key, label: key, type: def.type ?? \"string\", required: def.required });\n }\n }\n return out;\n}\n","/**\n * The seeding/coverage logic behind the shared `InputListEditor` (T3.2.1):\n * filling a Function/Endpoint's declared input list from the picked target's\n * resolved fields (`TargetSelector`'s A5/A7, `target-fields.ts`), and\n * flagging what a later target change no longer covers.\n *\n * **The policy (HITL-1, pinned).** Seed only when the input list is empty\n * AND the user has not touched it; once touched (any add/update/remove via\n * the row editor), a later target change never rewrites the list — it only\n * flags the required keys the new target no longer covers. This is the only\n * policy that cannot destroy typed work, and the flag is what T3.2.2's save\n * gate consumes.\n *\n * **Supersedes `target-fields.ts`'s `seedRowsFromFields`** — T3.1.1's\n * declared v1 stopgap (seed-a-wholly-empty-list-once, no touched/merge\n * concept). That symbol is deleted from `target-fields.ts`, not duplicated;\n * this module is its one home.\n *\n * **The pass-through guard** (the finding most likely to cause a silent\n * regression): the server dispatches an Endpoint's `action` arm on\n * `target.with === undefined` (`invoke-endpoint.ts:136-143`) — `{}` is\n * truthy, so an empty `with` does NOT pass through. `EndpointDef.input` (the\n * declared list this module seeds) is a SEPARATE field the server never\n * reads for dispatch at all, but the round-trip must still agree:\n * {@link inputsForSave} returns `undefined` (never `[]`) for an empty,\n * pass-through-mode list, so a previously authored pass-through Endpoint\n * opens and re-saves unchanged. A Function has no pass-through mode —\n * `emptyMeansPassthrough: false` never returns `undefined`, matching\n * `FunctionDef.inputs`'s non-nullable wire type (`draft.inputs.map` would\n * throw on `undefined`).\n *\n * Pure, React-free, `.ts`, no value import of `@w6w/ui` — mirrors\n * `workflow-validity.ts`/`target-fields.ts`'s shape so `node --test` can\n * load it directly (`@w6w/ui`'s barrel re-exports `.tsx`, which Node's\n * type-stripping cannot parse). `INPUT_TYPES` lives here rather than in\n * `InputListEditor.tsx` because this module's own seeding logic needs it.\n */\n\nimport { effectiveParam, matchesParamCondition } from \"@w6w/expr\";\nimport type { TargetField } from \"./target-fields.ts\";\n\n/** The input-row types the two builders offer (`ActionParam`'s subset). */\nexport const INPUT_TYPES = [\"string\", \"text\", \"number\", \"boolean\", \"json\", \"secret\"] as const;\n\n/**\n * One row of an input-contract list — `FunctionInput`/`EndpointInput`'s\n * common shape (`../api/types.ts`), mirrored locally so this pure module\n * never imports a value from a `.tsx`-reexporting barrel. Structurally\n * identical to both wire types, so a page's `draft.inputs`/`draft.input`\n * needs no cast at the `InputListEditor` boundary in either direction.\n */\nexport interface InputRow {\n key: string;\n label: string;\n type: string;\n required?: boolean;\n default?: unknown;\n hint?: string;\n}\n\n/**\n * Is there a wholly empty, still-untouched list to seed? Any manual edit —\n * add, update or remove, via the row editor's own `onChange` — makes the\n * list the user's forever after (HITL-1); the seeding effect itself must\n * never be what sets `touched`.\n */\nexport function shouldSeed(args: { rows: InputRow[]; touched: boolean }): boolean {\n return args.rows.length === 0 && !args.touched;\n}\n\n/**\n * `type` is the field's own type when {@link INPUT_TYPES} declares it,\n * otherwise `\"string\"` — an unlisted type (`section`, `select`, …) would\n * otherwise render a `<select>` with no matching `<option>` and silently\n * change the value.\n */\nfunction normalizeType(type: string): string {\n return (INPUT_TYPES as readonly string[]).includes(type) ? type : \"string\";\n}\n\n/**\n * `rows` plus one appended row per `fields` key not already present, in\n * field order. **Never modifies or removes an existing row, never\n * re-orders.** A seeded row is\n * `{ key, label: field.label ?? field.key, type, required: Boolean(field.required) }`\n * and nothing else — `default`/`hint` are deliberately not copied, because\n * the row editor cannot show or remove them and they would become invisible\n * state on the saved definition. Fields with a missing/blank key are\n * skipped; a duplicate key (in `fields`, or already present in `rows`)\n * seeds once.\n */\nexport function mergeSeed(rows: InputRow[], fields: TargetField[]): InputRow[] {\n const seen = new Set(rows.map((r) => r.key));\n const appended: InputRow[] = [];\n for (const field of fields) {\n const key = field.key;\n if (typeof key !== \"string\" || key.trim() === \"\" || seen.has(key)) continue;\n seen.add(key);\n appended.push({\n key,\n label: field.label ?? key,\n type: normalizeType(field.type),\n required: Boolean(field.required),\n });\n }\n return appended.length === 0 ? rows : [...rows, ...appended];\n}\n\n/**\n * Is `field` visible under the given effective-value lookup?\n * Delegates to `@w6w/expr`'s `matchesParamCondition` (all four arms).\n */\nfunction isFieldVisible(field: TargetField, effective: (key: string) => unknown): boolean {\n const c = field.showIf;\n if (!c) return true;\n return matchesParamCondition(c, effective);\n}\n\n/**\n * Does `default` satisfy \"usable\"? A usable default can stand in for an\n * explicitly mapped value — `false` and `0` are usable, `undefined`/`null`\n * and whitespace-only strings are not.\n * Implements the `v === undefined || v === null` / `v.trim() !== \"\"`\n * rejection from `packages/ui/src/StepBuilderModal.tsx:706-707`.\n */\nfunction hasUsableDefault(d: unknown): boolean {\n if (d === undefined || d === null) return false;\n if (typeof d === \"string\") return d.trim() !== \"\";\n return true;\n}\n\n/**\n * The required field keys `fields` declares that no row in `rows` covers,\n * in field order — what a target change leaves for the operator to notice\n * once the list is the user's (HITL-1) and can no longer be auto-filled.\n * Informational here: T3.2.2's save gate is what turns this into a block,\n * and imports this same predicate rather than forking a second copy of it.\n *\n * Skips a required field that is currently hidden by its own `showIf` or\n * that declares a usable `default` — mirroring\n * `packages/ui/src/StepBuilderModal.tsx:686-711`'s `requiredParamsFilled`.\n * `values` is the `with` mapping; omitting it leaves existing callers'\n * behaviour unchanged apart from the two new skips.\n */\nexport function uncoveredRequiredKeys(\n rows: InputRow[],\n fields: TargetField[],\n values?: Record<string, unknown>,\n): string[] {\n const covered = new Set(rows.map((r) => r.key));\n const effective = (key: string) =>\n values?.[key] !== undefined ? values[key] : fields.find((f) => f.key === key)?.default;\n const out: string[] = [];\n for (const field of fields) {\n if (!effectiveParam(field, effective).required) continue;\n const key = field.key;\n if (typeof key !== \"string\" || key.trim() === \"\" || covered.has(key) || out.includes(key)) {\n continue;\n }\n if (!isFieldVisible(field, effective)) continue;\n if (hasUsableDefault(field.default)) continue;\n out.push(key);\n }\n return out;\n}\n\n/**\n * The write-back both pages route their input list through (see the module\n * docstring's pass-through guard). The overloads let a call site that\n * passes the literal `emptyMeansPassthrough: false` (every Function save)\n * keep a non-nullable return type at compile time, matching\n * `FunctionDef.inputs`'s wire shape without a cast.\n */\nexport function inputsForSave(rows: InputRow[], opts: { emptyMeansPassthrough: false }): InputRow[];\nexport function inputsForSave(\n rows: InputRow[],\n opts: { emptyMeansPassthrough: boolean },\n): InputRow[] | undefined;\nexport function inputsForSave(\n rows: InputRow[],\n opts: { emptyMeansPassthrough: boolean },\n): InputRow[] | undefined {\n if (opts.emptyMeansPassthrough && rows.length === 0) return undefined;\n return rows;\n}\n","/**\n * The **save gate**'s arm dispatch (T3.2.2): given a picked target, decide\n * *which* key set counts as \"feeding\" its required fields — and when the\n * question does not apply at all — then hand the actual set difference to\n * {@link uncoveredRequiredKeys}.\n *\n * **This module deliberately owns no coverage rule of its own.**\n * `uncoveredRequiredKeys` lives in `./input-seeding.ts` because T3.2.1's\n * `InputListEditor` *renders* the uncovered-required flag from it. Two copies\n * of one coverage rule would drift, and the user would see a flag with no\n * block or a block with no flag. Everything below is dispatch: pick the\n * covered set, or skip.\n *\n * ## The five cases, each anchored to the line that decides it at runtime\n *\n * | # | case | gate |\n * |---|---|---|\n * | P1 | Endpoint, `action` arm, `target.with === undefined` | **skipped** — pass-through |\n * | P2 | Endpoint, `action` arm, `target.with` is an object (**incl. `{}`**) | required params must be non-blank cells of `with` |\n * | P3 | Endpoint, `function`/`workflow` arm, declared `input` list empty | **skipped** — no `with` mechanism exists on these arms |\n * | P4 | Endpoint, `function`/`workflow` arm, declared list non-empty | required target keys must appear as declared row keys |\n * | P5 | **Function**, always | required params must be non-blank cells of `impl.with` |\n *\n * P1 is `=== undefined` **only**. `bll/invoke-endpoint.ts:136-143` dispatches\n * `target.with ? resolveWith(…) : input.input`, and `{}` is truthy — so an\n * empty object does **not** pass through, and treating it as if it did would\n * ship exactly the unfed-required-field bug this gate exists to block. The\n * consequence, stated rather than fixed: `EndpointsPage`'s picker writes\n * `with: built.with ?? {}`, so an action-arm **pass-through Endpoint can no\n * longer be authored through the UI at all** — it can only be opened and\n * re-saved. That was already true server-side before this gate existed\n * (`FOLLOWUPS.md`).\n *\n * P1/P2 key on `target.with` and **never** on the declared list. That matters\n * because T3.2.1 made a deliberately emptied Endpoint list save `input`\n * *absent* rather than `[]` — so \"emptied\" and \"never declared\" are\n * indistinguishable on the wire, and a gate that read pass-through off the\n * list's emptiness would misread one for the other. P3's skip is justified by\n * the *absence of a `with` mechanism* on the callable arms, where the payload\n * always passes through by key identity, not by the list being empty.\n *\n * P5 has no skip: `bll/invoke-function.ts:101-107` calls\n * `resolveWith(impl.with, …)` unconditionally, so a Function has no\n * pass-through mode. With **no action chosen** the field list is empty and\n * coverage is vacuously satisfied, which is what preserves the deliberate\n * save-gate asymmetry — `FunctionsPage` stays saveable incomplete (its\n * `valid`/incomplete badge is the signal), while `EndpointsPage` keeps its\n * separate `targetIsBound` term.\n *\n * ## Known limitation — this gate is CLIENT-SIDE ONLY\n *\n * A determined API caller can still `POST /functions` or `POST /endpoints`\n * with a malformed definition. Both server `validateDefinition`s are\n * structural only (`api/functions.ts:26-37` checks the *types* of\n * `impl.uses.app`/`action`; `api/endpoints.ts:109-154` checks `target.kind`\n * plus its ref/uses fields and the `exposure.security` shape) — neither\n * invokes anything nor looks at coverage, so a dangling ref or an unmapped\n * required param stores fine and fails only at invoke time. Closing that is a\n * server-side write, a boundary expansion out of scope for this node; it is\n * stated here rather than papered over.\n *\n * Pure, React-free, `.ts`, no import of `@w6w/ui` — directly or transitively.\n * `./target-fields.ts`, `./input-seeding.ts` and `./with-mapping.ts` are all\n * `@w6w/ui`-free by the same design (`workflow-validity.ts`'s header explains\n * the wall: the barrel re-exports `.tsx`, which `node --test` cannot parse).\n * The normalized field list therefore arrives as a plain array parameter,\n * resolved by the caller — `TargetSelector`'s `onResolved` — exactly as\n * `workflow-validity.ts:69`'s injected `ValidityContext` does.\n */\n\nimport { type InputRow, uncoveredRequiredKeys } from \"./input-seeding.ts\";\nimport type { FunctionImplLike, TargetField, TargetLike } from \"./target-fields.ts\";\n\n/**\n * Check if a `with` mapping value is considered \"fed\" (non-empty).\n * A cell is \"fed\" when it contains a non-empty value:\n * - ExprValue objects are always considered fed (they have meaningful content)\n * - Strings are fed if non-blank after trimming\n * - Everything else (null, undefined, empty string) is not fed\n */\nfunction isFedValue(v: unknown): boolean {\n if (v == null) return false;\n if (typeof v === \"string\") return v.trim() !== \"\";\n if (typeof v === \"object\" && \"type\" in v && v.type === \"expr\") return true;\n // Legacy `{ \"$\": path }` format or any other object is considered fed\n return typeof v === \"object\";\n}\n\n/**\n * The mapping cells that actually feed something, shaped as the covered rows\n * {@link uncoveredRequiredKeys} diffs against. A cell is \"fed\" when it\n * contains a non-empty value — a whitespace-only literal maps nothing, and\n * `updateWith` deletes a cleared key outright.\n */\nfunction coveredRowsFromWith(withBlock: Record<string, unknown>): InputRow[] {\n const rows: InputRow[] = [];\n for (const key of Object.keys(withBlock)) {\n if (!isFedValue(withBlock[key])) continue;\n rows.push({ key, label: key, type: \"string\" });\n }\n return rows;\n}\n\n/**\n * The required target-field keys an Endpoint does **not** feed — P1–P4 above.\n * Empty means saveable as far as coverage is concerned; `EndpointsPage`'s own\n * `targetIsBound`/`key` terms are separate and survive unchanged.\n *\n * `fields` is the target's normalized field list as `TargetSelector` resolved\n * it. While a target's detail is still loading it is `[]`, so the gate is\n * vacuous until the fields arrive — this fails **open**, deliberately: an\n * unresolvable target (a deleted app, a failed fetch) must never trap an\n * author in a form they cannot save.\n */\nexport function uncoveredForEndpoint(args: {\n target: TargetLike;\n rows: InputRow[];\n fields: TargetField[];\n}): string[] {\n const { target, rows, fields } = args;\n if (target.kind === \"action\") {\n if (target.with === undefined) return []; // P1 — pass-through, nothing to check\n return uncoveredRequiredKeys(coveredRowsFromWith(target.with), fields, target.with); // P2\n }\n if (rows.length === 0) return []; // P3 — the callable arms have no `with` mechanism\n return uncoveredRequiredKeys(rows, fields); // P4 — key-name identity\n}\n\n/**\n * The required action-param keys a Function's `impl.with` does not map — P5.\n * No skip arm: a Function has no pass-through mode. An unbound Function\n * resolves to an empty `fields`, so this returns `[]` and the Functions save\n * gate keeps allowing a deliberately incomplete save.\n */\nexport function uncoveredForFunction(args: {\n impl: FunctionImplLike | undefined;\n fields: TargetField[];\n}): string[] {\n // Draft functions have no impl yet; no fields are covered\n if (!args.impl) {\n return args.fields.filter((f) => f.required).map((f) => f.key);\n }\n return uncoveredRequiredKeys(\n coveredRowsFromWith(args.impl.with ?? {}),\n args.fields,\n args.impl.with ?? {},\n );\n}\n","/**\n * Coerce a text field's value to the canonical input's declared type, for a callable's test-invoke\n * form. Empty ⇒ undefined (the field is omitted from the payload). Unparseable `number`/`json` text\n * is passed through raw, so the server's own validation names the problem.\n */\nexport function coerceInput(type: string, raw: string): unknown {\n if (raw === \"\") return undefined;\n switch (type) {\n case \"number\": {\n const n = Number(raw);\n return Number.isNaN(n) ? raw : n;\n }\n case \"boolean\":\n return raw === \"true\";\n case \"json\":\n try {\n return JSON.parse(raw);\n } catch {\n return raw;\n }\n default:\n return raw;\n }\n}\n"],"names":["targetRef","target","targetIsBound","implToTarget","impl","targetToImpl","implAfterRebind","prev","next","prevKind","same","p","paramsToFields","params","field","fieldsFromWorkflow","workflow","ctx","rawNodes","steps","seen","out","step","app","_a","defs","_b","def","key","INPUT_TYPES","shouldSeed","args","normalizeType","type","mergeSeed","rows","fields","r","appended","isFieldVisible","effective","c","matchesParamCondition","hasUsableDefault","d","uncoveredRequiredKeys","values","covered","effectiveParam","inputsForSave","opts","isFedValue","v","coveredRowsFromWith","withBlock","uncoveredForEndpoint","uncoveredForFunction","f","coerceInput","raw","n"],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ import { useQuery as u, useQueryClient as a, useMutation as l } from "@tanstack/react-query";
2
+ import { u as o } from "./client-context-CX61Bgw-.js";
3
+ const p = (n) => ["app-connections", n];
4
+ function d(n, e) {
5
+ return n.console.connections.listForApp(e);
6
+ }
7
+ function w(n, e = !0) {
8
+ const t = o();
9
+ return u({
10
+ queryKey: p(n),
11
+ queryFn: () => d(t, n),
12
+ enabled: e
13
+ });
14
+ }
15
+ const r = ["connections"];
16
+ function q(n) {
17
+ return n.connections.list();
18
+ }
19
+ function g() {
20
+ const n = o();
21
+ return u({ queryKey: r, queryFn: () => q(n) });
22
+ }
23
+ const y = (n) => ["connection", n];
24
+ function C(n, e) {
25
+ return n.console.connections.get(e);
26
+ }
27
+ function A(n) {
28
+ const e = o();
29
+ return u({ queryKey: y(n), queryFn: () => C(e, n) });
30
+ }
31
+ function D(n, e, t) {
32
+ return n.console.connections.create(e, t);
33
+ }
34
+ function K(n, e, t) {
35
+ return n.console.connections.update(e, t);
36
+ }
37
+ function M(n) {
38
+ const e = o(), t = a();
39
+ return l({
40
+ mutationFn: (c) => K(e, n, c),
41
+ onSuccess: () => {
42
+ t.invalidateQueries({ queryKey: r }), t.invalidateQueries({ queryKey: y(n) });
43
+ }
44
+ });
45
+ }
46
+ function h(n) {
47
+ const e = o(), t = a();
48
+ return l({
49
+ mutationFn: () => e.console.connections.test(n),
50
+ onSuccess: () => {
51
+ t.invalidateQueries({ queryKey: y(n) }), t.invalidateQueries({ queryKey: r });
52
+ }
53
+ });
54
+ }
55
+ const f = (n) => ["connection-dependents", n];
56
+ function Q(n, e) {
57
+ return n.console.connections.dependents(e);
58
+ }
59
+ function k(n, e = !0) {
60
+ const t = o();
61
+ return u({
62
+ queryKey: f(n),
63
+ queryFn: () => Q(t, n),
64
+ enabled: e,
65
+ // The answer must be fresh each time the confirm opens.
66
+ staleTime: 0,
67
+ gcTime: 0,
68
+ retry: !1
69
+ });
70
+ }
71
+ async function m(n, e) {
72
+ var t;
73
+ try {
74
+ return await n.console.connections.delete(e.id, { force: e.force === !0 }), { ok: !0 };
75
+ } catch (c) {
76
+ const i = c;
77
+ if ((i == null ? void 0 : i.status) === 409 && i.code === "connection_in_use") {
78
+ const s = (t = (i.raw ?? {}).error) == null ? void 0 : t.dependents;
79
+ return {
80
+ ok: !1,
81
+ dependents: {
82
+ callables: (s == null ? void 0 : s.callables) ?? [],
83
+ subscriptions: (s == null ? void 0 : s.subscriptions) ?? []
84
+ }
85
+ };
86
+ }
87
+ throw c;
88
+ }
89
+ }
90
+ function S() {
91
+ const n = o(), e = a();
92
+ return l({
93
+ mutationFn: (t) => m(n, t),
94
+ onSuccess: (t, { id: c }) => {
95
+ e.invalidateQueries({ queryKey: r }), e.invalidateQueries({ queryKey: f(c) });
96
+ }
97
+ });
98
+ }
99
+ export {
100
+ f as a,
101
+ y as b,
102
+ r as c,
103
+ p as d,
104
+ D as e,
105
+ m as f,
106
+ C as g,
107
+ Q as h,
108
+ d as i,
109
+ K as j,
110
+ k,
111
+ q as l,
112
+ A as m,
113
+ w as n,
114
+ S as o,
115
+ h as p,
116
+ M as q,
117
+ g as u
118
+ };
119
+ //# sourceMappingURL=connections-CzsCyIxY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connections-CzsCyIxY.js","sources":["../src/repos/connections.ts"],"sourcesContent":["/**\n * The connections-for-one-app repo — the Target selector's connection picker.\n *\n * Moved from Studio's `repos/connections.ts` (B-3a); the Studio file re-exports these names. The\n * client comes from `useEmbedClient()`. D-12e moved the rest of the file here (list, single,\n * create, update, test, delete); Studio's `repos/connections.ts` is now a pure re-export shim.\n */\nimport { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport type { ConnectionSummary, W6WClient } from \"@w6w/sdk\";\nimport type { ConnectionDependents, ConnectionTestResult } from \"@w6w/sdk/console\";\nimport { useEmbedClient } from \"../draft/client-context.ts\";\n\nexport type { ConnectionSummary } from \"@w6w/sdk\";\n\n// The bodies are the SDK's (this module may not import @w6w/ui, see repos-graph.test.ts); they are\n// forwarded verbatim and the ui adapter's `CreateConnectionBody` / `updateConnection` bodies must\n// stay assignable to them (the hosts' tsc enforces it).\nexport type CreateConnectionBody = Parameters<W6WClient[\"console\"][\"connections\"][\"create\"]>[1];\nexport type UpdateConnectionBody = Parameters<W6WClient[\"console\"][\"connections\"][\"update\"]>[1];\n\nexport const connectionsForAppKey = (appId: string) => [\"app-connections\", appId] as const;\n\nexport function listConnectionsForApp(\n client: W6WClient,\n appId: string,\n): Promise<ConnectionSummary[]> {\n return client.console.connections.listForApp(appId);\n}\n\n/**\n * `enabled` defaults to `true`. `TargetSelector` passes `app !== \"\"` — its original\n * pre-migration guard, preserved exactly.\n */\nexport function useConnectionsForAppQuery(appId: string, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: connectionsForAppKey(appId),\n queryFn: () => listConnectionsForApp(client, appId),\n enabled,\n });\n}\n\n// ── connections (list, all apps) ──────────────────────────────────────\n// BASE partner surface — client.connections.list() already exists. There is no\n// console.connections.list(); do NOT route this one through client.console.connections.\n\nexport const connectionsKey = [\"connections\"] as const;\n\nexport function listConnections(client: W6WClient): Promise<ConnectionSummary[]> {\n return client.connections.list();\n}\n\nexport function useConnectionsQuery() {\n const client = useEmbedClient();\n return useQuery({ queryKey: connectionsKey, queryFn: () => listConnections(client) });\n}\n\n// ── connection (single) ───────────────────────────────────────────────\n\nexport const connectionKey = (id: string) => [\"connection\", id] as const;\n\nexport function getConnection(client: W6WClient, id: string): Promise<ConnectionSummary> {\n return client.console.connections.get(id);\n}\n\nexport function useConnectionQuery(id: string) {\n const client = useEmbedClient();\n return useQuery({ queryKey: connectionKey(id), queryFn: () => getConnection(client, id) });\n}\n\n// ── create / update (plain fetchers) ──────────────────────────────────\n\nexport function createConnection(\n client: W6WClient,\n appId: string,\n body: CreateConnectionBody,\n): Promise<ConnectionSummary> {\n return client.console.connections.create(appId, body);\n}\n\n/** The write `W6WEmbedProvider` hands the ui adapter as `updateConnection` (the SDK adapter has none). */\nexport function updateConnection(\n client: W6WClient,\n id: string,\n body: UpdateConnectionBody,\n): Promise<ConnectionSummary> {\n return client.console.connections.update(id, body);\n}\n\n// ── mutations ────────────────────────────────────────────────────────\n\nexport function useUpdateConnectionMutation(connectionId: string) {\n const client = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (body: UpdateConnectionBody) => updateConnection(client, connectionId, body),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: connectionsKey });\n qc.invalidateQueries({ queryKey: connectionKey(connectionId) });\n },\n });\n}\n\nexport function useTestConnectionMutation(connectionId: string) {\n const client = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (): Promise<ConnectionTestResult> => client.console.connections.test(connectionId),\n onSuccess: () => {\n qc.invalidateQueries({ queryKey: connectionKey(connectionId) });\n qc.invalidateQueries({ queryKey: connectionsKey });\n },\n });\n}\n\n// ── dependents / delete ──────────────────────────────────────────────\n\nexport type { ConnectionDependents } from \"@w6w/sdk/console\";\n\nexport const connectionDependentsKey = (id: string) => [\"connection-dependents\", id] as const;\n\nexport function getConnectionDependents(\n client: W6WClient,\n id: string,\n): Promise<ConnectionDependents> {\n return client.console.connections.dependents(id);\n}\n\n/** What a delete would disable. `enabled` gates the fetch (the modal is closed → no request). */\nexport function useConnectionDependentsQuery(id: string, enabled = true) {\n const client = useEmbedClient();\n return useQuery({\n queryKey: connectionDependentsKey(id),\n queryFn: () => getConnectionDependents(client, id),\n enabled,\n // The answer must be fresh each time the confirm opens.\n staleTime: 0,\n gcTime: 0,\n retry: false,\n });\n}\n\nexport type DeleteConnectionResult = { ok: true } | { ok: false; dependents: ConnectionDependents };\n\n/**\n * Delete with an optional `force`. A 409 `connection_in_use` is data — `{ ok: false, dependents }`\n * — not a thrown error; every other failure rejects.\n */\nexport async function deleteConnection(\n client: W6WClient,\n args: { id: string; force?: boolean },\n): Promise<DeleteConnectionResult> {\n try {\n await client.console.connections.delete(args.id, { force: args.force === true });\n return { ok: true };\n } catch (e) {\n const err = e as { status?: unknown; code?: unknown; raw?: unknown };\n if (err?.status === 409 && err.code === \"connection_in_use\") {\n // Wire: { error: { code, message, dependents } } — see wrappers/node/src/connections.ts.\n const raw = (err.raw ?? {}) as { error?: { dependents?: Partial<ConnectionDependents> } };\n const deps = raw.error?.dependents;\n return {\n ok: false,\n dependents: {\n callables: deps?.callables ?? [],\n subscriptions: deps?.subscriptions ?? [],\n },\n };\n }\n throw e;\n }\n}\n\nexport function useDeleteConnectionMutation() {\n const client = useEmbedClient();\n const qc = useQueryClient();\n return useMutation({\n mutationFn: (args: { id: string; force?: boolean }) => deleteConnection(client, args),\n onSuccess: (_r, { id }) => {\n qc.invalidateQueries({ queryKey: connectionsKey });\n qc.invalidateQueries({ queryKey: connectionDependentsKey(id) });\n },\n });\n}\n"],"names":["connectionsForAppKey","appId","listConnectionsForApp","client","useConnectionsForAppQuery","enabled","useEmbedClient","useQuery","connectionsKey","listConnections","useConnectionsQuery","connectionKey","id","getConnection","useConnectionQuery","createConnection","body","updateConnection","useUpdateConnectionMutation","connectionId","qc","useQueryClient","useMutation","useTestConnectionMutation","connectionDependentsKey","getConnectionDependents","useConnectionDependentsQuery","deleteConnection","args","e","err","deps","_a","useDeleteConnectionMutation","_r"],"mappings":"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"}