treege 3.0.0-beta.5 → 3.0.0-beta.51

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 (181) hide show
  1. package/LICENSE +18 -12
  2. package/README.md +313 -52
  3. package/dist/DefaultInputs-tsNo-XJa.js +1761 -0
  4. package/dist/ThemeContext-DRLlkF0n.js +1353 -0
  5. package/dist/editor/components/input/ComboboxWithCreate.d.ts +2 -1
  6. package/dist/editor/components/styles/EditorStyles.d.ts +2 -0
  7. package/dist/editor/constants/defaultNode.d.ts +1 -1
  8. package/dist/editor/constants/edgeTypes.d.ts +3 -2
  9. package/dist/editor/constants/inputTypeIcons.d.ts +3 -0
  10. package/dist/editor/constants/nodeSpacing.d.ts +33 -0
  11. package/dist/editor/constants/nodeTypes.d.ts +4 -5
  12. package/dist/editor/context/OpenApiContext.d.ts +79 -0
  13. package/dist/editor/context/TreegeEditorContext.d.ts +60 -1
  14. package/dist/editor/features/TreegeEditor/TreegeEditor.d.ts +1 -1
  15. package/dist/editor/features/TreegeEditor/controls/MiniMapControl.d.ts +6 -0
  16. package/dist/editor/features/TreegeEditor/dialogs/AuthorizeDialog.d.ts +20 -0
  17. package/dist/editor/features/TreegeEditor/dialogs/ChangeNodeTypeDialog.d.ts +2 -0
  18. package/dist/editor/features/TreegeEditor/dialogs/DeleteNodeDialog.d.ts +2 -0
  19. package/dist/editor/features/TreegeEditor/dialogs/HeadersDialog.d.ts +19 -0
  20. package/dist/editor/features/TreegeEditor/dialogs/OpenApiDialog.d.ts +6 -0
  21. package/dist/editor/features/TreegeEditor/edges/ConditionalEdge.d.ts +2 -2
  22. package/dist/editor/features/TreegeEditor/edges/DefaultEdge.d.ts +3 -0
  23. package/dist/editor/features/TreegeEditor/forms/OptionsSourceForm.d.ts +7 -0
  24. package/dist/editor/features/TreegeEditor/forms/SubmitConfigForm.d.ts +7 -0
  25. package/dist/editor/features/TreegeEditor/inputs/ApiUrlCombobox.d.ts +30 -0
  26. package/dist/editor/features/TreegeEditor/inputs/ComboboxPattern.d.ts +2 -1
  27. package/dist/editor/features/TreegeEditor/inputs/OptionImageField.d.ts +6 -0
  28. package/dist/editor/features/TreegeEditor/inputs/SelectNodeGroup.d.ts +22 -1
  29. package/dist/editor/features/TreegeEditor/layout/AutoLayout.d.ts +15 -0
  30. package/dist/editor/features/TreegeEditor/nodes/TreegeNode.d.ts +5 -0
  31. package/dist/editor/features/TreegeEditor/nodes/components/BottomHandleDropdown.d.ts +9 -0
  32. package/dist/editor/features/TreegeEditor/nodes/components/NodeGroupBadge.d.ts +6 -0
  33. package/dist/editor/features/TreegeEditor/nodes/components/NodeImage.d.ts +5 -0
  34. package/dist/editor/features/TreegeEditor/nodes/components/NodeImageButton.d.ts +6 -0
  35. package/dist/editor/features/TreegeEditor/nodes/components/NodeInputPreview.d.ts +12 -0
  36. package/dist/editor/features/TreegeEditor/nodes/components/NodeLabelInput.d.ts +10 -0
  37. package/dist/editor/features/TreegeEditor/nodes/components/NodeMoreMenu.d.ts +6 -0
  38. package/dist/editor/features/TreegeEditor/nodes/components/NodeRequiredButton.d.ts +6 -0
  39. package/dist/editor/features/TreegeEditor/nodes/components/NodeStackOrderButtons.d.ts +6 -0
  40. package/dist/editor/features/TreegeEditor/nodes/components/NodeTypeBadge.d.ts +7 -0
  41. package/dist/editor/features/TreegeEditor/nodes/layout/NodeWrapper.d.ts +4 -2
  42. package/dist/editor/features/TreegeEditor/panel/AIGeneratorDialog.d.ts +16 -0
  43. package/dist/editor/features/TreegeEditor/panel/ActionsPanel.d.ts +7 -2
  44. package/dist/editor/features/TreegeEditor/panel/MultiSelectionPanel.d.ts +7 -0
  45. package/dist/editor/hooks/useAvailableParentFields.d.ts +13 -0
  46. package/dist/editor/hooks/useFlowActions.d.ts +6 -2
  47. package/dist/editor/hooks/useFlowConnections.d.ts +14 -0
  48. package/dist/editor/hooks/useHistoryStore.d.ts +26 -0
  49. package/dist/editor/hooks/useIsStackedEdge.d.ts +8 -0
  50. package/dist/editor/hooks/useNodesSelection.d.ts +5 -5
  51. package/dist/editor/hooks/useStackPosition.d.ts +14 -0
  52. package/dist/editor/hooks/useUndoRedo.d.ts +31 -0
  53. package/dist/editor/types/ai.d.ts +65 -0
  54. package/dist/editor/types/editor.d.ts +71 -9
  55. package/dist/editor/types/openapi.d.ts +81 -0
  56. package/dist/editor/utils/aiFlowGenerator.d.ts +5 -0
  57. package/dist/editor/utils/dagreLayout.d.ts +8 -0
  58. package/dist/editor/utils/edge.d.ts +14 -0
  59. package/dist/editor/utils/groupColor.d.ts +14 -0
  60. package/dist/editor/utils/image.d.ts +7 -0
  61. package/dist/editor/utils/inputTypeIcon.d.ts +6 -0
  62. package/dist/editor/utils/openapi.d.ts +35 -0
  63. package/dist/editor/utils/stackPositionIndex.d.ts +9 -0
  64. package/dist/editor-HlDmu9kn.js +5831 -0
  65. package/dist/editor.js +3 -8
  66. package/dist/main.js +4 -53
  67. package/dist/renderer/context/TreegeConfigContext.d.ts +3 -27
  68. package/dist/renderer/context/TreegeRendererContext.d.ts +100 -2
  69. package/dist/renderer/features/TreegeRenderer/native/TreegeRenderer.d.ts +19 -11
  70. package/dist/renderer/features/TreegeRenderer/native/components/DefaultFormWrapper.d.ts +7 -7
  71. package/dist/renderer/features/TreegeRenderer/native/components/DefaultInputWrapper.d.ts +9 -0
  72. package/dist/renderer/features/TreegeRenderer/native/components/DefaultInputs.d.ts +21 -15
  73. package/dist/renderer/features/TreegeRenderer/native/components/DefaultStep.d.ts +3 -0
  74. package/dist/renderer/features/TreegeRenderer/native/components/DefaultSubmitButton.d.ts +9 -7
  75. package/dist/renderer/features/TreegeRenderer/native/components/DefaultSubmitButtonWrapper.d.ts +11 -0
  76. package/dist/renderer/features/TreegeRenderer/native/components/DefaultUI.d.ts +8 -7
  77. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultAddressInput.d.ts +3 -0
  78. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultAutocompleteInput.d.ts +3 -0
  79. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultCheckboxInput.d.ts +3 -0
  80. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultDateInput.d.ts +3 -0
  81. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultDateRangeInput.d.ts +3 -0
  82. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultFileInput.d.ts +3 -0
  83. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultHiddenInput.d.ts +3 -0
  84. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultHttpInput.d.ts +3 -0
  85. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultNumberInput.d.ts +3 -0
  86. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultPasswordInput.d.ts +3 -0
  87. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultRadioInput.d.ts +3 -0
  88. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultSelectInput.d.ts +3 -0
  89. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultSwitchInput.d.ts +3 -0
  90. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultTextInput.d.ts +3 -0
  91. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultTextareaInput.d.ts +3 -0
  92. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultTimeInput.d.ts +3 -0
  93. package/dist/renderer/features/TreegeRenderer/native/components/inputs/DefaultTimeRangeInput.d.ts +3 -0
  94. package/dist/renderer/features/TreegeRenderer/useTreegeRenderer.d.ts +92 -24
  95. package/dist/renderer/features/TreegeRenderer/web/TreegeRenderer.d.ts +1 -1
  96. package/dist/renderer/features/TreegeRenderer/web/components/DefaultFormWrapper.d.ts +1 -1
  97. package/dist/renderer/features/TreegeRenderer/web/components/DefaultInputWrapper.d.ts +9 -0
  98. package/dist/renderer/features/TreegeRenderer/web/components/DefaultStep.d.ts +3 -0
  99. package/dist/renderer/features/TreegeRenderer/web/components/DefaultSubmitButton.d.ts +1 -1
  100. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultAddressInput.d.ts +1 -1
  101. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultAutocompleteInput.d.ts +1 -1
  102. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultCheckboxInput.d.ts +1 -1
  103. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultDateInput.d.ts +1 -1
  104. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultDateRangeInput.d.ts +1 -1
  105. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultFileInput.d.ts +1 -1
  106. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultHiddenInput.d.ts +1 -1
  107. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultHttpInput.d.ts +1 -1
  108. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultNumberInput.d.ts +1 -1
  109. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultPasswordInput.d.ts +1 -1
  110. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultRadioInput.d.ts +1 -1
  111. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultSelectInput.d.ts +1 -1
  112. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultSubmitInput.d.ts +3 -0
  113. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultSwitchInput.d.ts +1 -1
  114. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultTextAreaInput.d.ts +1 -1
  115. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultTextInput.d.ts +1 -1
  116. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultTimeInput.d.ts +1 -1
  117. package/dist/renderer/features/TreegeRenderer/web/components/inputs/DefaultTimeRangeInput.d.ts +1 -1
  118. package/dist/renderer/features/TreegeRenderer/web/components/styles/RendererStyles.d.ts +2 -0
  119. package/dist/renderer/hooks/useInputOptions.d.ts +28 -0
  120. package/dist/renderer/hooks/useRenderNode.d.ts +57 -0
  121. package/dist/renderer/hooks/useSubmitHandler.d.ts +35 -0
  122. package/dist/renderer/hooks/useTranslate.d.ts +6 -4
  123. package/dist/renderer/index.d.ts +3 -1
  124. package/dist/renderer/index.native.d.ts +19 -0
  125. package/dist/renderer/types/renderer.d.ts +131 -33
  126. package/dist/renderer/utils/flow.d.ts +1 -18
  127. package/dist/renderer/utils/form.d.ts +22 -2
  128. package/dist/renderer/utils/http.d.ts +129 -0
  129. package/dist/renderer/utils/node.d.ts +18 -1
  130. package/dist/renderer/utils/sanitize.d.ts +85 -0
  131. package/dist/renderer/utils/sanitize.native.d.ts +69 -0
  132. package/dist/renderer/utils/step.d.ts +27 -0
  133. package/dist/renderer/utils/submit.d.ts +48 -0
  134. package/dist/renderer-native.d.ts +2 -0
  135. package/dist/renderer-native.js +3580 -0
  136. package/dist/renderer.js +3 -46
  137. package/dist/shared/components/ui/badge.d.ts +2 -2
  138. package/dist/shared/components/ui/button.d.ts +3 -3
  139. package/dist/shared/components/ui/collapsible.d.ts +1 -1
  140. package/dist/shared/components/ui/command.d.ts +1 -1
  141. package/dist/shared/components/ui/dropdown-menu.d.ts +1 -1
  142. package/dist/shared/components/ui/field.d.ts +24 -0
  143. package/dist/shared/components/ui/form.d.ts +1 -1
  144. package/dist/shared/components/ui/popover.d.ts +4 -2
  145. package/dist/shared/components/ui/select.d.ts +3 -1
  146. package/dist/shared/components/ui/sheet.d.ts +1 -1
  147. package/dist/shared/components/ui/toggle-group.d.ts +7 -0
  148. package/dist/shared/components/ui/toggle.d.ts +9 -0
  149. package/dist/shared/components/ui/tooltip.d.ts +1 -1
  150. package/dist/shared/constants/colors.d.ts +45 -0
  151. package/dist/shared/constants/inputType.d.ts +1 -0
  152. package/dist/shared/constants/node.d.ts +0 -1
  153. package/dist/shared/context/ThemeContext.d.ts +2 -0
  154. package/dist/shared/context/ThemeContext.native.d.ts +22 -0
  155. package/dist/shared/hooks/useMediaQuery.d.ts +12 -0
  156. package/dist/shared/hooks/useThemeColors.d.ts +37 -0
  157. package/dist/shared/locales/ar.json.d.ts +221 -18
  158. package/dist/shared/locales/de.json.d.ts +222 -19
  159. package/dist/shared/locales/en.json.d.ts +223 -20
  160. package/dist/shared/locales/es.json.d.ts +222 -19
  161. package/dist/shared/locales/fr.json.d.ts +222 -19
  162. package/dist/shared/locales/it.json.d.ts +222 -19
  163. package/dist/shared/locales/pt.json.d.ts +222 -19
  164. package/dist/shared/types/edge.d.ts +6 -0
  165. package/dist/shared/types/node.d.ts +109 -7
  166. package/dist/shared/utils/inputTypeGuards.d.ts +7 -0
  167. package/dist/shared/utils/nodeTypeGuards.d.ts +1 -6
  168. package/package.json +48 -22
  169. package/dist/ThemeContext-D4xMOrdt.js +0 -759
  170. package/dist/TreegeEditor-B8FP1rKR.js +0 -2153
  171. package/dist/TreegeRenderer-BOCobRLr.js +0 -1414
  172. package/dist/editor/features/TreegeEditor/forms/FlowNodeForm.d.ts +0 -2
  173. package/dist/editor/features/TreegeEditor/inputs/SelectInputType.d.ts +0 -7
  174. package/dist/editor/features/TreegeEditor/nodes/FlowNode.d.ts +0 -6
  175. package/dist/editor/features/TreegeEditor/nodes/GroupNode.d.ts +0 -6
  176. package/dist/editor/features/TreegeEditor/nodes/InputNode.d.ts +0 -6
  177. package/dist/editor/features/TreegeEditor/nodes/UINode.d.ts +0 -6
  178. package/dist/editor/hooks/useEdgesSelection.d.ts +0 -11
  179. package/dist/renderer/features/TreegeRenderer/native/components/DefaultGroup.d.ts +0 -7
  180. package/dist/renderer/features/TreegeRenderer/web/components/DefaultGroup.d.ts +0 -6
  181. /package/dist/editor/components/{data-display/logo.d.ts → branding/Logo.d.ts} +0 -0
@@ -1,7 +1,8 @@
1
1
  import { Node } from '@xyflow/react';
2
2
  import { FormEvent, ReactNode } from 'react';
3
3
  import { SerializableFile } from '../utils/file';
4
- import { Flow, InputNodeData, InputType, TreegeNodeData, UINodeData, UIType } from '../../shared/types/node';
4
+ import { FlowStep } from '../utils/step';
5
+ import { Flow, GroupNodeData, HttpHeader, InputNodeData, InputOption, InputType, TreegeNodeData, UINodeData, UIType } from '../../shared/types/node';
5
6
  /**
6
7
  * Type mapping for input values based on input type
7
8
  */
@@ -18,6 +19,7 @@ export type InputValueTypeMap = {
18
19
  password: string;
19
20
  radio: string;
20
21
  select: string | string[];
22
+ submit: undefined;
21
23
  switch: boolean;
22
24
  text: string;
23
25
  textarea: string;
@@ -28,20 +30,35 @@ export type InputValueTypeMap = {
28
30
  * Form values stored during rendering
29
31
  */
30
32
  export type FormValues = Record<string, any>;
33
+ export type Meta = {
34
+ httpResponse?: unknown;
35
+ };
31
36
  /**
32
37
  * Union of all possible input value types
33
38
  */
34
- export type InputValue = string | number | boolean | string[] | SerializableFile | SerializableFile[] | [string, string] | [string | undefined, string | undefined] | null;
39
+ export type InputValue = string | number | boolean | string[] | SerializableFile | SerializableFile[] | [string, string] | [string | undefined, string | undefined] | null | undefined;
35
40
  /**
36
41
  * Props for input components with dynamic value typing
37
42
  * All form state is provided via props for easier custom component implementation
38
43
  */
39
44
  export type InputRenderProps<T extends InputType = InputType> = {
45
+ /**
46
+ * The node data for this input field
47
+ */
40
48
  node: Node<InputNodeData>;
41
49
  /**
42
50
  * Current value of the input field (typed based on input type when T is specified)
43
51
  */
44
52
  value: InputValueTypeMap[T];
53
+ /**
54
+ * Unique field ID (nodeId)
55
+ */
56
+ id: string;
57
+ /**
58
+ * Field name (resolved using priority: name > label > nodeId)
59
+ * Use this for the name and id attributes of the input element
60
+ */
61
+ name: string;
45
62
  /**
46
63
  * Function to update the input value
47
64
  * @param value - The new value (typed based on input type when T is specified)
@@ -51,6 +68,46 @@ export type InputRenderProps<T extends InputType = InputType> = {
51
68
  * Validation error message for this field (if any)
52
69
  */
53
70
  error?: string;
71
+ /**
72
+ * Translated label (already processed with current language)
73
+ */
74
+ label?: string;
75
+ /**
76
+ * Translated placeholder (already processed with current language)
77
+ */
78
+ placeholder?: string;
79
+ /**
80
+ * Translated helper text (already processed with current language)
81
+ */
82
+ helperText?: string;
83
+ /**
84
+ * Missing required fields on form submit (for submit inputs)
85
+ */
86
+ missingRequiredFields?: string[];
87
+ /**
88
+ * Whether the form is currently being submitted (for submit inputs)
89
+ */
90
+ isSubmitting?: boolean;
91
+ /**
92
+ * Editor-only extension slot: when provided, option-based renderers (radio,
93
+ * checkbox) call this for each option to paint inline extras next to it
94
+ * (e.g. value preview, edit / delete buttons). `variant` is a renderer-side
95
+ * layout hint (e.g. `"card"` for radio cards). Returning `null` skips the
96
+ * slot for that option. Left undefined in runtime so the renderers stay
97
+ * runtime-pure.
98
+ */
99
+ renderOptionExtras?: (option: {
100
+ option: InputOption;
101
+ index: number;
102
+ variant?: string;
103
+ }) => ReactNode;
104
+ /**
105
+ * Editor-only layout flag. When `true`, option-based renderers force their
106
+ * option labels to a single truncated line (block + max-w-full + truncate)
107
+ * and reserve room on the right for the `renderOptionExtras` overlay.
108
+ * Defaults to `false` (multi-line, runtime-pure).
109
+ */
110
+ compactOptions?: boolean;
54
111
  };
55
112
  export type UiRenderProps = {
56
113
  node: Node<UINodeData>;
@@ -68,6 +125,44 @@ export type NodeRenderProps = {
68
125
  export type InputRenderers = {
69
126
  [K in InputType]?: (props: InputRenderProps<K>) => ReactNode;
70
127
  };
128
+ /**
129
+ * Props passed to a step renderer. Steps are derived at runtime from the flow's
130
+ * groups: each contiguous slice of visible nodes sharing the same `parentId`
131
+ * (or no parent — orphan steps) becomes one step.
132
+ */
133
+ export type StepRenderProps = {
134
+ /** The step being rendered (its group id and ordered child nodes). */
135
+ step: FlowStep;
136
+ /** Hidden group node carrying the step's metadata (label) — undefined for orphan steps. */
137
+ groupNode?: Node<GroupNodeData>;
138
+ /** Zero-based index of this step in the current step sequence. */
139
+ stepIndex: number;
140
+ /** Total number of steps currently visible. Recomputes when branching changes. */
141
+ totalSteps: number;
142
+ /** True when this is the first step (Back should be hidden/disabled). */
143
+ isFirstStep: boolean;
144
+ /**
145
+ * True when this is the last visible step. The renderer turns Continue
146
+ * into a submit action on the last step.
147
+ */
148
+ isLastStep: boolean;
149
+ /** Whether all required visible inputs of the step are filled. */
150
+ canContinue: boolean;
151
+ /** Submission in progress (passed through from `useTreegeRenderer`). */
152
+ isSubmitting?: boolean;
153
+ /** Advance to the previous step. No-op on the first step. */
154
+ onBack: () => void;
155
+ /**
156
+ * Advance to the next step (or trigger submit on the last step). The wrapper
157
+ * passes `isLastStep` so the implementation can decide between an in-flow
158
+ * advance and a form submit.
159
+ */
160
+ onContinue: () => void;
161
+ /** Translated label of the group, or empty string for orphan steps. */
162
+ label?: string;
163
+ /** The rendered child nodes belonging to this step. */
164
+ children: ReactNode;
165
+ };
71
166
  /**
72
167
  * Custom renderer components
73
168
  */
@@ -82,21 +177,32 @@ export type TreegeRendererComponents = {
82
177
  */
83
178
  ui?: Partial<Record<UIType, (props: NodeRenderProps) => ReactNode>>;
84
179
  /**
85
- * Custom group container renderer
180
+ * Custom step renderer — wraps the current step's nodes and renders the
181
+ * Back/Continue navigation. Defaults are provided by `DefaultStep` (web/native).
86
182
  */
87
- group?: (props: NodeRenderProps) => ReactNode;
183
+ step?: (props: StepRenderProps) => ReactNode;
88
184
  /**
89
185
  * Custom form wrapper
90
186
  */
91
187
  form?: (props: {
92
188
  children: ReactNode;
93
- onSubmit: (e: FormEvent) => void;
189
+ onSubmit: (e: FormEvent<HTMLFormElement>) => void;
94
190
  }) => ReactNode;
95
191
  /**
96
- * Custom submit button (pure button without wrapper)
192
+ * Custom submit button (supports both web and native variants)
193
+ * Web variant: { label?: string; disabled?: boolean; ...otherHTMLAttributes }
194
+ * Native variant: { children?: ReactNode; disabled?: boolean; isSubmitting?: boolean; onPress?: () => void }
97
195
  */
98
196
  submitButton?: (props: {
99
197
  label?: string;
198
+ disabled?: boolean;
199
+ [key: string]: unknown;
200
+ } | {
201
+ children?: ReactNode;
202
+ disabled?: boolean;
203
+ isSubmitting?: boolean;
204
+ onPress?: () => void;
205
+ [key: string]: unknown;
100
206
  }) => ReactNode;
101
207
  /**
102
208
  * Custom submit button wrapper (e.g., for tooltip with missing fields)
@@ -115,6 +221,12 @@ export type TreegeRendererConfig = {
115
221
  * Custom component renderers
116
222
  */
117
223
  components?: TreegeRendererComponents;
224
+ /**
225
+ * Global HTTP headers applied to every request issued by the renderer
226
+ * (HTTP inputs, submit buttons). Field-level headers with the same key
227
+ * (case-insensitive) take precedence over these.
228
+ */
229
+ headers?: HttpHeader[];
118
230
  /**
119
231
  * Google Maps API key for address autocomplete
120
232
  * If not provided, falls back to free Nominatim (OpenStreetMap)
@@ -138,50 +250,36 @@ export type TreegeRendererConfig = {
138
250
  };
139
251
  /**
140
252
  * Props for the TreegeRenderer component
253
+ *
254
+ * Inherits all configuration fields from TreegeRendererConfig (components,
255
+ * headers, googleApiKey, language, theme, validationMode) and adds the
256
+ * instance-specific ones (flows, callbacks, initial values, etc.).
141
257
  */
142
- export type TreegeRendererProps = {
258
+ export interface TreegeRendererProps extends TreegeRendererConfig {
143
259
  /**
144
- * Custom component renderers
260
+ * Additional class name for the renderer container
145
261
  */
146
- components?: TreegeRendererComponents;
262
+ className?: string;
147
263
  /**
148
- * Flow or array of flows
149
- * - If a single Flow: renders that flow
150
- * - If an array: first flow is the main flow, others are sub-flows available for FlowNodes
264
+ * Flow to render. `null` / `undefined` renders nothing.
151
265
  */
152
- flows?: Flow | Flow[] | null;
153
- /**
154
- * Google Maps API key for address autocomplete
155
- * If not provided, falls back to free Nominatim (OpenStreetMap)
156
- */
157
- googleApiKey?: string;
266
+ flows?: Flow | null;
158
267
  /**
159
268
  * Initial form values
160
269
  */
161
270
  initialValues?: FormValues;
162
- /**
163
- * Current language for translations
164
- */
165
- language?: string;
166
271
  /**
167
272
  * Callback when form values change
168
273
  */
169
274
  onChange?: (values: FormValues) => void;
170
275
  /**
171
276
  * Callback when form is submitted
277
+ * @param values - Form values (keyed by field name or node ID)
278
+ * @param meta - Optional metadata about the submission (e.g., HTTP response data)
172
279
  */
173
- onSubmit?: (values: FormValues) => void;
174
- /**
175
- * Theme for the renderer
176
- * @default "dark"
177
- */
178
- theme?: "dark" | "light";
280
+ onSubmit?: (values: FormValues, meta?: Meta) => void;
179
281
  /**
180
282
  * Custom validation function
181
283
  */
182
284
  validate?: (values: FormValues, nodes: Node<TreegeNodeData>[]) => Record<string, string>;
183
- /**
184
- * Validation mode
185
- */
186
- validationMode?: "onChange" | "onSubmit";
187
- };
285
+ }
@@ -1,7 +1,7 @@
1
1
  import { Edge, Node } from '@xyflow/react';
2
2
  import { FormValues } from '../types/renderer';
3
3
  import { ConditionalEdgeData } from '../../shared/types/edge';
4
- import { Flow, TreegeNodeData } from '../../shared/types/node';
4
+ import { TreegeNodeData } from '../../shared/types/node';
5
5
  /**
6
6
  * Result from computing the flow render state
7
7
  * Contains everything needed to render the form and determine its state
@@ -72,20 +72,3 @@ export declare const findStartNode: (nodes: Node<TreegeNodeData>[], edges: Edge[
72
72
  * @returns Complete flow render state (visible nodes, end-of-path flag, etc.)
73
73
  */
74
74
  export declare const getFlowRenderState: (nodes: Node<TreegeNodeData>[], edges: Edge<ConditionalEdgeData>[], formValues: FormValues) => FlowRenderState;
75
- /**
76
- * Merge multiple flows into a single flow by recursively replacing FlowNodes with their target flow's nodes
77
- *
78
- * This function takes a flow or an array of flows, automatically detects the main flow, then:
79
- * 1. Replaces each FlowNode with the nodes from its target flow
80
- * 2. Preserves the order of nodes by inserting sub-flow nodes at the FlowNode position
81
- * 3. Redirects edges that point to FlowNodes to the first node of the target flow
82
- * 4. Connects the last nodes of sub-flows to the nodes that followed the FlowNode
83
- *
84
- * Main flow detection:
85
- * - The main flow is automatically identified as the one that references other flows but is not referenced itself
86
- * - This allows flows to be passed in any order without breaking the merge logic
87
- *
88
- * @param flows - A single Flow or an array of flows (can be null/undefined)
89
- * @returns A single merged Flow containing all nodes and edges
90
- */
91
- export declare const mergeFlows: (flows?: Flow | Flow[] | null) => Flow;
@@ -20,7 +20,27 @@ export declare const checkFormFieldHasValue: (fieldName: string | undefined, for
20
20
  /**
21
21
  * Convert internal form values (keyed by nodeId) to external format (keyed by name)
22
22
  * When multiple nodes share the same name, later values overwrite earlier ones
23
- * example: convertFormValuesToNamedFormat({ id1: 'Alice', id2: 'Bob' }, [ { id: 'id1', data: { name: 'firstName' } }, { id: 'id2', data: { name: 'lastName' } } ])
24
- * returns { firstName: 'Alice', lastName: 'Bob' }
23
+ * Priority for key naming: name > label (en) > nodeId
24
+ * example: convertFormValuesToNamedFormat({ id1: 'Alice', id2: 'Bob' }, [ { id: 'id1', data: { name: 'firstName' } }, { id: 'id2', data: { label: { en: 'Last Name' } } } ])
25
+ * returns { firstName: 'Alice', 'Last Name': 'Bob' }
25
26
  */
26
27
  export declare const convertFormValuesToNamedFormat: (formValues: FormValues, nodes: Node<InputNodeData>[]) => Record<string, unknown>;
28
+ /**
29
+ * Apply transformation to a reference field value
30
+ * @param value - The source value to transform
31
+ * @param transformFunction - The transformation function to apply
32
+ * @param objectMapping - Optional mapping for toObject transformation
33
+ * @returns The transformed value
34
+ */
35
+ export declare const applyReferenceTransformation: (value: unknown, transformFunction: "toString" | "toNumber" | "toBoolean" | "toArray" | "toObject" | null | undefined, objectMapping?: Array<{
36
+ sourceKey: string;
37
+ targetKey: string;
38
+ }>) => unknown;
39
+ /**
40
+ * Calculate updated values for fields with reference defaults
41
+ * @param inputNodes - Array of input nodes
42
+ * @param formValues - Current form values
43
+ * @param prevFormValues - Previous form values (for change detection)
44
+ * @returns Object containing fields that need to be updated
45
+ */
46
+ export declare const calculateReferenceFieldUpdates: (inputNodes: Node<InputNodeData>[], formValues: FormValues, prevFormValues: FormValues) => FormValues;
@@ -0,0 +1,129 @@
1
+ import { FormValues } from '../types/renderer';
2
+ import { HttpHeader, InputOption, OptionsSourceMapping } from '../../shared/types/node';
3
+ /**
4
+ * Merge multiple lists of HTTP headers. Later sources override earlier ones
5
+ * when they specify the same key (case-insensitive comparison, since HTTP
6
+ * header names are case-insensitive). The casing of the latest occurrence
7
+ * is preserved in the output.
8
+ */
9
+ export declare const mergeHttpHeaders: (...sources: (HttpHeader[] | undefined)[]) => HttpHeader[];
10
+ /**
11
+ * Result of an HTTP request
12
+ */
13
+ export interface HttpRequestResult {
14
+ /**
15
+ * Whether the request was successful (2xx status code)
16
+ */
17
+ success: boolean;
18
+ /**
19
+ * Response data (parsed JSON or raw text)
20
+ */
21
+ data?: unknown;
22
+ /**
23
+ * Error message if request failed
24
+ */
25
+ error?: string;
26
+ /**
27
+ * HTTP status code
28
+ */
29
+ status?: number;
30
+ /**
31
+ * HTTP status text
32
+ */
33
+ statusText?: string;
34
+ }
35
+ /**
36
+ * Options for making an HTTP request
37
+ */
38
+ export interface HttpRequestOptions {
39
+ /**
40
+ * The URL to call (should already have variables replaced)
41
+ */
42
+ url: string;
43
+ /**
44
+ * HTTP method
45
+ */
46
+ method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
47
+ /**
48
+ * Request headers
49
+ */
50
+ headers?: HttpHeader[];
51
+ /**
52
+ * Request body (for POST/PUT/PATCH)
53
+ */
54
+ body?: string;
55
+ /**
56
+ * Optional abort signal to cancel the request
57
+ */
58
+ signal?: AbortSignal;
59
+ }
60
+ /**
61
+ * Make an HTTP request with common error handling and response parsing
62
+ *
63
+ * This is a shared utility used by both HTTP inputs and submit buttons
64
+ * to ensure consistent behavior across the library.
65
+ *
66
+ * @param options - Request options
67
+ * @returns Promise with request result
68
+ */
69
+ export declare const makeHttpRequest: (options: HttpRequestOptions) => Promise<HttpRequestResult>;
70
+ /**
71
+ * Replace template variables in a string with actual values from form data
72
+ *
73
+ * Uses {{fieldId}} syntax for all replacements (URLs, JSON bodies, etc.)
74
+ *
75
+ * Smart JSON handling:
76
+ * - Strings: automatically wrapped in quotes and escaped
77
+ * - Numbers/Booleans: converted to JSON-safe format
78
+ * - Arrays/Objects: JSON.stringify
79
+ *
80
+ * @param template - The template string containing variables
81
+ * @param values - Form values to substitute
82
+ * @param options - Replacement options
83
+ * @param options.encode - Whether to URL-encode the replaced values (for URLs)
84
+ * @param options.json - Whether to use smart JSON handling (for request bodies)
85
+ * @returns The string with variables replaced
86
+ *
87
+ * @example
88
+ * // For URLs (with encoding)
89
+ * replaceTemplateVariables("https://api.com/users/{{userId}}", { userId: "john doe" }, { encode: true })
90
+ * // => "https://api.com/users/john%20doe"
91
+ *
92
+ * // For JSON bodies (smart handling)
93
+ * replaceTemplateVariables('{"name": {{userName}}}', { userName: "John" }, { json: true })
94
+ * // => '{"name": "John"}'
95
+ *
96
+ * replaceTemplateVariables('{"age": {{userAge}}}', { userAge: 25 }, { json: true })
97
+ * // => '{"age": 25}'
98
+ */
99
+ export declare const replaceTemplateVariables: (template: string | undefined, values: FormValues, options?: {
100
+ encode?: boolean;
101
+ json?: boolean;
102
+ }) => string;
103
+ /**
104
+ * Replace template variables in response data (for redirect URLs)
105
+ *
106
+ * Supports {{response.field}} format to access response data
107
+ *
108
+ * @param template - The template string containing variables
109
+ * @param responseData - Response data object
110
+ * @returns The string with variables replaced
111
+ */
112
+ export declare const replaceResponseVariables: (template: string | undefined, responseData: unknown) => string;
113
+ /**
114
+ * Extract a value from an object using a path that supports dot notation
115
+ * and array indexing. Examples:
116
+ * - "data.users" → obj.data.users
117
+ * - "results[0].name" → obj.results[0].name
118
+ *
119
+ * @param obj - The object to extract value from
120
+ * @param path - The path expression (empty string returns the object as-is)
121
+ * @returns The value at the path, or undefined if not found
122
+ */
123
+ export declare const getValueByPath: (obj: unknown, path: string) => unknown;
124
+ /**
125
+ * Project a list-shaped HTTP response into InputOption objects, applying
126
+ * a field-to-property mapping. Returns an empty array when the data is not
127
+ * iterable or required fields are missing.
128
+ */
129
+ export declare const extractOptionsFromResponse: (response: unknown, responsePath: string | undefined, mapping: OptionsSourceMapping) => InputOption[];
@@ -6,9 +6,26 @@ import { InputNodeData, TreegeNodeData } from '../../shared/types/node';
6
6
  * @returns Array of input nodes only
7
7
  */
8
8
  export declare const getInputNodes: (nodes: Node<TreegeNodeData>[]) => Node<InputNodeData>[];
9
+ /**
10
+ * Resolve the key name for an input node using priority: name > label (en) > nodeId
11
+ * This is the single source of truth for key resolution across the application
12
+ * @param node - The input node
13
+ * @returns The resolved key (name, label, or node ID)
14
+ */
15
+ export declare const resolveNodeKey: (node: Node<InputNodeData>) => string;
16
+ /**
17
+ * Resolve the placeholder text for an input, falling back to the static
18
+ * "newAnswer" translation for textfield-like types when the user has not
19
+ * defined a placeholder for the current language.
20
+ * @param data - The input node data
21
+ * @param language - The current language code
22
+ * @returns The resolved placeholder string (empty string if none available)
23
+ */
24
+ export declare const resolveInputPlaceholder: (data: InputNodeData, language: string) => string;
9
25
  /**
10
26
  * Get the field name (DOM name attribute) for a given node ID
11
- * Uses node.data.name if available, otherwise falls back to nodeId
27
+ * Priority: name > label (en) > nodeId
28
+ * This must match the logic in convertFormValuesToNamedFormat for consistency
12
29
  * @param nodeId - The ID of the input node
13
30
  * @param nodes - Array of input nodes
14
31
  * @returns The field name to use in the DOM, or undefined if node not found
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Configuration for DOMPurify sanitization
3
+ */
4
+ interface SanitizeOptions {
5
+ /**
6
+ * Allow only plain text (strip all HTML tags)
7
+ * @default true
8
+ */
9
+ plainTextOnly?: boolean;
10
+ /**
11
+ * Custom allowed tags (when plainTextOnly is false)
12
+ */
13
+ allowedTags?: string[];
14
+ /**
15
+ * Custom allowed attributes (when plainTextOnly is false)
16
+ */
17
+ allowedAttributes?: string[];
18
+ }
19
+ /**
20
+ * Sanitizes user input to prevent XSS attacks
21
+ *
22
+ * This utility wraps DOMPurify and provides secure defaults for the treege library.
23
+ * It should be used on all user-provided content before rendering, especially:
24
+ * - Labels from node data
25
+ * - Helper text
26
+ * - Placeholder text
27
+ * - Any content from HTTP responses
28
+ *
29
+ * @param input - The string to sanitize
30
+ * @param options - Sanitization options
31
+ * @returns Sanitized string safe for rendering
32
+ *
33
+ * @example
34
+ * // Plain text only (default behavior)
35
+ * sanitize('<script>alert("xss")</script>Hello')
36
+ * // => 'Hello'
37
+ *
38
+ * @example
39
+ * // Allow safe HTML tags
40
+ * sanitize('<b>Bold text</b><script>alert("xss")</script>', { plainTextOnly: false })
41
+ * // => '<b>Bold text</b>'
42
+ *
43
+ * @example
44
+ * // Custom allowed tags
45
+ * sanitize('<a href="http://example.com">Link</a>', {
46
+ * plainTextOnly: false,
47
+ * allowedTags: ['a'],
48
+ * allowedAttributes: ['href']
49
+ * })
50
+ * // => '<a href="http://example.com">Link</a>'
51
+ */
52
+ export declare const sanitize: (input: string | undefined | null, options?: SanitizeOptions) => string;
53
+ /**
54
+ * Sanitizes data from HTTP responses
55
+ *
56
+ * This function recursively sanitizes all string values in an object or array.
57
+ * Useful for cleaning data received from external APIs before displaying it.
58
+ *
59
+ * Protection against:
60
+ * - Circular references: Uses WeakSet to detect and handle circular objects
61
+ * - Deep nesting attacks: Limits recursion depth to prevent DoS
62
+ * - XSS attacks: Sanitizes all string values
63
+ *
64
+ * @param data - The data to sanitize (can be any type)
65
+ * @param options - Sanitization options
66
+ * @param depth - Current recursion depth (internal use)
67
+ * @param seen - WeakSet to track visited objects (internal use)
68
+ * @returns Sanitized data with same structure
69
+ *
70
+ * @example
71
+ * sanitizeHttpResponse({
72
+ * name: 'John <script>xss</script>',
73
+ * nested: { title: 'Hello <b>world</b>' }
74
+ * })
75
+ * // => { name: 'John ', nested: { title: 'Hello <b>world</b>' } }
76
+ *
77
+ * @example
78
+ * // Handles circular references gracefully
79
+ * const obj = { name: 'Test' };
80
+ * obj.self = obj;
81
+ * sanitizeHttpResponse(obj)
82
+ * // => { name: 'Test', self: { name: 'Test' } } // circular ref broken
83
+ */
84
+ export declare const sanitizeHttpResponse: (data: unknown, options?: SanitizeOptions, depth?: number, seen?: WeakSet<object>) => unknown;
85
+ export {};
@@ -0,0 +1,69 @@
1
+ /**
2
+ * React Native implementation of sanitization utilities
3
+ * Does not use DOMPurify as it depends on browser DOM
4
+ */
5
+ /**
6
+ * Configuration for sanitization
7
+ */
8
+ interface SanitizeOptions {
9
+ /**
10
+ * Allow only plain text (strip all HTML tags)
11
+ * @default true
12
+ */
13
+ plainTextOnly?: boolean;
14
+ /**
15
+ * Custom allowed tags (when plainTextOnly is false)
16
+ * Note: In React Native, HTML tags are always stripped
17
+ */
18
+ allowedTags?: string[];
19
+ /**
20
+ * Custom allowed attributes (when plainTextOnly is false)
21
+ * Note: In React Native, attributes are not applicable
22
+ */
23
+ allowedAttributes?: string[];
24
+ }
25
+ /**
26
+ * Sanitizes user input to prevent XSS attacks
27
+ *
28
+ * React Native implementation that strips all HTML tags and decodes entities.
29
+ * Since React Native doesn't render HTML, we focus on cleaning text content.
30
+ *
31
+ * @param input - The string to sanitize
32
+ * @param options - Sanitization options (maintained for API compatibility)
33
+ * @returns Sanitized string safe for rendering
34
+ *
35
+ * @example
36
+ * sanitize('<script>alert("xss")</script>Hello')
37
+ * // => 'Hello'
38
+ *
39
+ * @example
40
+ * sanitize('<b>Bold text</b><script>alert("xss")</script>')
41
+ * // => 'Bold text'
42
+ */
43
+ export declare const sanitize: (input: string | undefined | null, _options?: SanitizeOptions) => string;
44
+ /**
45
+ * Sanitizes data from HTTP responses
46
+ *
47
+ * This function recursively sanitizes all string values in an object or array.
48
+ * Useful for cleaning data received from external APIs before displaying it.
49
+ *
50
+ * Protection against:
51
+ * - Circular references: Uses WeakSet to detect and handle circular objects
52
+ * - Deep nesting attacks: Limits recursion depth to prevent DoS
53
+ * - XSS attacks: Sanitizes all string values
54
+ *
55
+ * @param data - The data to sanitize (can be any type)
56
+ * @param options - Sanitization options
57
+ * @param depth - Current recursion depth (internal use)
58
+ * @param seen - WeakSet to track visited objects (internal use)
59
+ * @returns Sanitized data with same structure
60
+ *
61
+ * @example
62
+ * sanitizeHttpResponse({
63
+ * name: 'John <script>xss</script>',
64
+ * nested: { title: 'Hello <b>world</b>' }
65
+ * })
66
+ * // => { name: 'John ', nested: { title: 'Hello world' } }
67
+ */
68
+ export declare const sanitizeHttpResponse: (data: unknown, options?: SanitizeOptions, depth?: number, seen?: WeakSet<object>) => unknown;
69
+ export {};
@@ -0,0 +1,27 @@
1
+ import { Node } from '@xyflow/react';
2
+ import { TreegeNodeData } from '../../shared/types/node';
3
+ /**
4
+ * A renderer step — a contiguous slice of visible nodes that share the same
5
+ * `parentId` (group id) or no parent (orphan step).
6
+ *
7
+ * Steps are derived from the flow's visible nodes at render time; the editor's
8
+ * group nodes carry only metadata (label) and are no longer rendered.
9
+ */
10
+ export type FlowStep = {
11
+ /**
12
+ * Group id owning the step, or null for orphan steps (nodes without `parentId`).
13
+ */
14
+ groupId: string | null;
15
+ /**
16
+ * The actual nodes (input + ui) rendered in this step, in flow order.
17
+ */
18
+ nodes: Node<TreegeNodeData>[];
19
+ };
20
+ /**
21
+ * Partition `visibleNodes` into ordered steps. A new step is started every
22
+ * time the `parentId` of the next renderable node changes (i.e. the flow
23
+ * crosses a group boundary, or moves between an orphan and a grouped node).
24
+ *
25
+ * Group nodes themselves are skipped — they're metadata only.
26
+ */
27
+ export declare const computeSteps: (visibleNodes: Node<TreegeNodeData>[]) => FlowStep[];