@notmrabhi/flowforge 0.1.41 → 0.1.44

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 (68) hide show
  1. package/dist/GatewayBranchEdge-CMY30xhz.js +2 -0
  2. package/dist/GatewayBranchEdge-CMY30xhz.js.map +1 -0
  3. package/dist/{GatewayBranchEdge-F2AGJpun.js → GatewayBranchEdge-CrgczPYJ.js} +161 -153
  4. package/dist/GatewayBranchEdge-CrgczPYJ.js.map +1 -0
  5. package/dist/{SchemaBuilderDrawer-CUzYWGCN.js → SchemaBuilderDrawer-DlmInnSC.js} +33 -33
  6. package/dist/{SchemaBuilderDrawer-CUzYWGCN.js.map → SchemaBuilderDrawer-DlmInnSC.js.map} +1 -1
  7. package/dist/{SchemaBuilderDrawer-CiSdfXzJ.js → SchemaBuilderDrawer-KUOXc7K_.js} +2 -2
  8. package/dist/{SchemaBuilderDrawer-CiSdfXzJ.js.map → SchemaBuilderDrawer-KUOXc7K_.js.map} +1 -1
  9. package/dist/canvas.cjs +1 -1
  10. package/dist/canvas.d.ts +131 -1
  11. package/dist/canvas.js +2 -2
  12. package/dist/core.cjs +1 -1
  13. package/dist/core.d.ts +39 -0
  14. package/dist/core.js +22 -23
  15. package/dist/core.js.map +1 -1
  16. package/dist/defaultUi.cjs +1 -1
  17. package/dist/defaultUi.js +1 -1
  18. package/dist/form.cjs +1 -1
  19. package/dist/form.d.ts +121 -0
  20. package/dist/form.js +36 -33
  21. package/dist/{index-B8-KKaH_.js → index-AISQhG1t.js} +2 -2
  22. package/dist/{index-B8-KKaH_.js.map → index-AISQhG1t.js.map} +1 -1
  23. package/dist/index-BDDJrQn0.js +10 -0
  24. package/dist/index-BDDJrQn0.js.map +1 -0
  25. package/dist/{index-Buv1ylwP.js → index-CBJiDDQc.js} +2 -2
  26. package/dist/{index-Buv1ylwP.js.map → index-CBJiDDQc.js.map} +1 -1
  27. package/dist/{index-DjKhaaWf.js → index-CbdFoSw3.js} +2 -2
  28. package/dist/{index-DjKhaaWf.js.map → index-CbdFoSw3.js.map} +1 -1
  29. package/dist/{index-CiU9_8f1.js → index-DU-niBi3.js} +2 -2
  30. package/dist/{index-CiU9_8f1.js.map → index-DU-niBi3.js.map} +1 -1
  31. package/dist/{index-B74jTc2b.js → index-y_v8Qog1.js} +3124 -3005
  32. package/dist/index-y_v8Qog1.js.map +1 -0
  33. package/dist/index.cjs +1 -1
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.ts +143 -1
  36. package/dist/index.js +81 -79
  37. package/dist/index.js.map +1 -1
  38. package/dist/nodeRegistry.cjs +1 -1
  39. package/dist/nodeRegistry.cjs.map +1 -1
  40. package/dist/nodeRegistry.d.ts +39 -0
  41. package/dist/nodeRegistry.js +543 -23
  42. package/dist/nodeRegistry.js.map +1 -1
  43. package/dist/{templateSkeletons-BQQ7UKp6.js → templateSkeletons-CHrd4Z5h.js} +375 -373
  44. package/dist/templateSkeletons-CHrd4Z5h.js.map +1 -0
  45. package/dist/templateSkeletons-CtknKiGO.js +2 -0
  46. package/dist/templateSkeletons-CtknKiGO.js.map +1 -0
  47. package/package.json +1 -1
  48. package/dist/GatewayBranchEdge-Dvkwkx-b.js +0 -2
  49. package/dist/GatewayBranchEdge-Dvkwkx-b.js.map +0 -1
  50. package/dist/GatewayBranchEdge-F2AGJpun.js.map +0 -1
  51. package/dist/index-B6xrei80.js +0 -87
  52. package/dist/index-B6xrei80.js.map +0 -1
  53. package/dist/index-B74jTc2b.js.map +0 -1
  54. package/dist/index-BrJBVztu.js +0 -2
  55. package/dist/index-BrJBVztu.js.map +0 -1
  56. package/dist/index-CXmgrKoe.js +0 -2
  57. package/dist/index-CXmgrKoe.js.map +0 -1
  58. package/dist/index-CqMPyOkL.js +0 -10
  59. package/dist/index-CqMPyOkL.js.map +0 -1
  60. package/dist/index-Dcur-XJ9.js +0 -36
  61. package/dist/index-Dcur-XJ9.js.map +0 -1
  62. package/dist/subWorkflowDescriptor-DYOYgBzX.js +0 -535
  63. package/dist/subWorkflowDescriptor-DYOYgBzX.js.map +0 -1
  64. package/dist/subWorkflowDescriptor-JDKi2INh.js +0 -2
  65. package/dist/subWorkflowDescriptor-JDKi2INh.js.map +0 -1
  66. package/dist/templateSkeletons-BQQ7UKp6.js.map +0 -1
  67. package/dist/templateSkeletons-C00QyIgk.js +0 -2
  68. package/dist/templateSkeletons-C00QyIgk.js.map +0 -1
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-CqMPyOkL.js"),a=require("./SchemaBuilderDrawer-CiSdfXzJ.js");require("react/jsx-runtime");require("react");require("@mui/material");require("react-icons/md");const l=require("./index-BrJBVztu.js"),n=require("./index-CXmgrKoe.js"),o=require("./templateSkeletons-C00QyIgk.js"),u=require("./messages-O9Tw_XXR.js"),d=require("./bpmn-CcuE2X_Q.js"),i=require("./GatewayBranchEdge-Dvkwkx-b.js"),r=require("./subWorkflowDescriptor-JDKi2INh.js");class c{constructor(){this.channels=new Map}register(t,s){this.channels.set(t,s)}get(t){return this.channels.get(t)}list(){return Array.from(this.channels.entries()).map(([t,s])=>({key:t,...s}))}has(t){return this.channels.has(t)}}const p=new c;exports.DynamicFormRenderer=e.DynamicFormRenderer;exports.FF=e.FF;exports.FlowForgeRegistry=e.FlowForgeRegistry;exports.FlowForm=e.FlowForm;exports.FormulaInput=e.FormulaInput;exports.InfiniteSelectField=e.InfiniteSelectField;exports.TablePickerField=e.TablePickerField;exports.VariablePicker=e.VariablePicker;exports.VariablePickerProvider=e.VariablePickerProvider;exports.astHasRefs=e.astHasRefs;exports.astToTokens=e.astToTokens;exports.buildEvaluationPayload=e.buildEvaluationPayload;exports.buildFieldConfig=e.buildFieldConfig;exports.buildFormulaPath=e.buildFormulaPath;exports.buildSelectStyles=e.buildSelectStyles;exports.buildValidationSchema=e.buildValidationSchema;exports.dataSourceRegistry=e.dataSourceRegistry;exports.errorTextStyle=e.errorTextStyle;exports.extractLabel=e.extractLabel;exports.fieldRegistry=e.fieldRegistry;exports.hasFormulaTokens=e.hasFormulaTokens;exports.helperTextStyle=e.helperTextStyle;exports.inputStyle=e.inputStyle;exports.isFormula=e.isFormula;exports.parseToAST=e.parseToAST;exports.serializeAST=e.serializeAST;exports.serializeASTAsConfig=e.serializeASTAsConfig;exports.serializeConditionExpressions=e.serializeConditionExpressions;exports.stripFormulaTokens=e.stripFormulaTokens;exports.tokenize=e.tokenize;exports.unwrapFormula=e.unwrapFormula;exports.useVariablePickerContext=e.useVariablePickerContext;exports.wrapFormula=e.wrapFormula;exports.FIELD_TYPE_OPTIONS=a.FIELD_TYPE_OPTIONS;exports.SchemaBuilder=a.SchemaBuilder;exports.SchemaBuilderDrawer=a.SchemaBuilderDrawer;exports.useFlowForm=a.useFlowForm;exports.NodeTypeRegistry=l.NodeTypeRegistry;exports.nodeTypeRegistry=l.nodeTypeRegistry;exports.TemplateRegistry=n.TemplateRegistry;exports.templateRegistry=n.templateRegistry;exports.FlowForgeCanvas=o.FlowForgeCanvas;exports.FlowForgeHeader=o.FlowForgeHeader;exports.SubWorkflowPreviewDrawer=o.SubWorkflowPreviewDrawer;exports.WorkflowCanvas=o.FlowForgeCanvas;exports.WorkflowExecutionHistory=o.WorkflowExecutionHistory;exports.WorkflowTemplateLibrary=o.WorkflowTemplateLibrary;exports.accessRequestSkeleton=o.accessRequestSkeleton;exports.offboardingSkeleton=o.offboardingSkeleton;exports.userOnboardingSkeleton=o.userOnboardingSkeleton;exports.webhookIntegrationSkeleton=o.webhookIntegrationSkeleton;exports.defaultFlowForgeMessages=u.defaultFlowForgeMessages;exports.loadWorkflowFromBpmn=d.loadWorkflowFromBpmn;exports.saveWorkflowToBpmn=d.saveWorkflowToBpmn;exports.ActionNode=i.ActionNode;exports.ApprovalNode=i.ApprovalNode;exports.EdgeWithPlusLabel=i.EdgeWithPlusLabel;exports.EndNode=i.EndNode;exports.FilterNode=i.FilterNode;exports.RestApiNode=i.RestApiNode;exports.StartNode=i.StartNode;exports.TriggerNode=i.TriggerNode;exports.WebhookTriggerNode=i.WebhookTriggerNode;exports.builtInNodeTypes=i.builtInNodeTypes;exports.baseNodeDefaults=r.baseNodeDefaults;exports.conditionBranchDescriptor=r.conditionBranchDescriptor;exports.defineNode=r.defineNode;exports.endEventDescriptor=r.endEventDescriptor;exports.makeSubWorkflowDescriptor=r.makeSubWorkflowDescriptor;exports.notificationDescriptor=r.notificationDescriptor;exports.restApiDescriptor=r.restApiDescriptor;exports.startEventDescriptor=r.startEventDescriptor;exports.subWorkflowDescriptor=r.subWorkflowDescriptor;exports.webhookTriggerDescriptor=r.webhookTriggerDescriptor;exports.webhookTriggerTemplate=r.webhookTriggerTemplate;exports.notificationChannelRegistry=p;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-BDDJrQn0.js"),s=require("./SchemaBuilderDrawer-KUOXc7K_.js");require("react/jsx-runtime");require("react");require("@mui/material");require("react-icons/md");const r=require("./nodeRegistry.cjs"),l=require("./templateRegistry.cjs"),o=require("./templateSkeletons-CtknKiGO.js"),d=require("./messages-O9Tw_XXR.js"),n=require("./bpmn-CcuE2X_Q.js"),i=require("./GatewayBranchEdge-CMY30xhz.js");class u{constructor(){this.channels=new Map}register(t,a){this.channels.set(t,a)}get(t){return this.channels.get(t)}list(){return Array.from(this.channels.entries()).map(([t,a])=>({key:t,...a}))}has(t){return this.channels.has(t)}}const c=new u;exports.DynamicFormRenderer=e.DynamicFormRenderer;exports.FF=e.FF;exports.FlowForgeRegistry=e.FlowForgeRegistry;exports.FlowForm=e.FlowForm;exports.FormulaInput=e.FormulaInput;exports.InfiniteSelectField=e.InfiniteSelectField;exports.OptionsResolversProvider=e.OptionsResolversProvider;exports.TablePickerField=e.TablePickerField;exports.VariablePicker=e.VariablePicker;exports.VariablePickerProvider=e.VariablePickerProvider;exports.astHasRefs=e.astHasRefs;exports.astToTokens=e.astToTokens;exports.buildEvaluationPayload=e.buildEvaluationPayload;exports.buildFieldConfig=e.buildFieldConfig;exports.buildFormulaPath=e.buildFormulaPath;exports.buildSelectStyles=e.buildSelectStyles;exports.buildValidationSchema=e.buildValidationSchema;exports.dataSourceRegistry=e.dataSourceRegistry;exports.errorTextStyle=e.errorTextStyle;exports.extractLabel=e.extractLabel;exports.fieldRegistry=e.fieldRegistry;exports.hasFormulaTokens=e.hasFormulaTokens;exports.helperTextStyle=e.helperTextStyle;exports.inputStyle=e.inputStyle;exports.isFormula=e.isFormula;exports.parseToAST=e.parseToAST;exports.serializeAST=e.serializeAST;exports.serializeASTAsConfig=e.serializeASTAsConfig;exports.serializeConditionExpressions=e.serializeConditionExpressions;exports.stripFormulaTokens=e.stripFormulaTokens;exports.tokenize=e.tokenize;exports.unwrapFormula=e.unwrapFormula;exports.useDynamicOptions=e.useDynamicOptions;exports.useOptionsResolvers=e.useOptionsResolvers;exports.useVariablePickerContext=e.useVariablePickerContext;exports.wrapFormula=e.wrapFormula;exports.FIELD_TYPE_OPTIONS=s.FIELD_TYPE_OPTIONS;exports.SchemaBuilder=s.SchemaBuilder;exports.SchemaBuilderDrawer=s.SchemaBuilderDrawer;exports.useFlowForm=s.useFlowForm;exports.NodeTypeRegistry=r.NodeTypeRegistry;exports.baseNodeDefaults=r.baseNodeDefaults;exports.conditionBranchDescriptor=r.conditionBranchDescriptor;exports.defineNode=r.defineNode;exports.endEventDescriptor=r.endEventDescriptor;exports.makeSubWorkflowDescriptor=r.makeSubWorkflowDescriptor;exports.nodeTypeRegistry=r.nodeTypeRegistry;exports.notificationDescriptor=r.notificationDescriptor;exports.restApiDescriptor=r.restApiDescriptor;exports.startEventDescriptor=r.startEventDescriptor;exports.subWorkflowDescriptor=r.subWorkflowDescriptor;exports.webhookTriggerDescriptor=r.webhookTriggerDescriptor;exports.webhookTriggerTemplate=r.webhookTriggerTemplate;exports.TemplateRegistry=l.TemplateRegistry;exports.templateRegistry=l.templateRegistry;exports.FlowForgeCanvas=o.FlowForgeCanvas;exports.FlowForgeHeader=o.FlowForgeHeader;exports.SubWorkflowPreviewDrawer=o.SubWorkflowPreviewDrawer;exports.WorkflowCanvas=o.FlowForgeCanvas;exports.WorkflowExecutionHistory=o.WorkflowExecutionHistory;exports.WorkflowTemplateLibrary=o.WorkflowTemplateLibrary;exports.accessRequestSkeleton=o.accessRequestSkeleton;exports.offboardingSkeleton=o.offboardingSkeleton;exports.userOnboardingSkeleton=o.userOnboardingSkeleton;exports.webhookIntegrationSkeleton=o.webhookIntegrationSkeleton;exports.defaultFlowForgeMessages=d.defaultFlowForgeMessages;exports.loadWorkflowFromBpmn=n.loadWorkflowFromBpmn;exports.saveWorkflowToBpmn=n.saveWorkflowToBpmn;exports.ActionNode=i.ActionNode;exports.ApprovalNode=i.ApprovalNode;exports.EdgeWithPlusLabel=i.EdgeWithPlusLabel;exports.EndNode=i.EndNode;exports.FilterNode=i.FilterNode;exports.RestApiNode=i.RestApiNode;exports.StartNode=i.StartNode;exports.TriggerNode=i.TriggerNode;exports.WebhookTriggerNode=i.WebhookTriggerNode;exports.builtInNodeTypes=i.builtInNodeTypes;exports.notificationChannelRegistry=c;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","sources":["../src/notificationChannelRegistry/index.ts"],"sourcesContent":["export interface NotificationChannelOption {\n value: string;\n label: string;\n}\n\nexport interface NotificationChannelConfig {\n label: string;\n /** Fetch recipients/channels for this notification channel at runtime */\n fetchRecipients?: () => Promise<NotificationChannelOption[]>;\n}\n\nclass NotificationChannelRegistry {\n private channels = new Map<string, NotificationChannelConfig>();\n\n register(key: string, config: NotificationChannelConfig): void {\n this.channels.set(key, config);\n }\n\n get(key: string): NotificationChannelConfig | undefined {\n return this.channels.get(key);\n }\n\n list(): Array<{ key: string } & NotificationChannelConfig> {\n return Array.from(this.channels.entries()).map(([key, cfg]) => ({ key, ...cfg }));\n }\n\n has(key: string): boolean {\n return this.channels.has(key);\n }\n}\n\nexport const notificationChannelRegistry = new NotificationChannelRegistry();\nexport default NotificationChannelRegistry;\n"],"names":["NotificationChannelRegistry","key","config","cfg","notificationChannelRegistry"],"mappings":"8hBAWA,MAAMA,CAA4B,CAAlC,aAAA,CACE,KAAQ,aAAe,GAAuC,CAE9D,SAASC,EAAaC,EAAyC,CAC7D,KAAK,SAAS,IAAID,EAAKC,CAAM,CAC/B,CAEA,IAAID,EAAoD,CACtD,OAAO,KAAK,SAAS,IAAIA,CAAG,CAC9B,CAEA,MAA2D,CACzD,OAAO,MAAM,KAAK,KAAK,SAAS,QAAA,CAAS,EAAE,IAAI,CAAC,CAACA,EAAKE,CAAG,KAAO,CAAE,IAAAF,EAAK,GAAGE,GAAM,CAClF,CAEA,IAAIF,EAAsB,CACxB,OAAO,KAAK,SAAS,IAAIA,CAAG,CAC9B,CACF,CAEO,MAAMG,EAA8B,IAAIJ"}
1
+ {"version":3,"file":"index.cjs","sources":["../src/notificationChannelRegistry/index.ts"],"sourcesContent":["export interface NotificationChannelOption {\n value: string;\n label: string;\n}\n\nexport interface NotificationChannelConfig {\n label: string;\n /** Fetch recipients/channels for this notification channel at runtime */\n fetchRecipients?: () => Promise<NotificationChannelOption[]>;\n}\n\nclass NotificationChannelRegistry {\n private channels = new Map<string, NotificationChannelConfig>();\n\n register(key: string, config: NotificationChannelConfig): void {\n this.channels.set(key, config);\n }\n\n get(key: string): NotificationChannelConfig | undefined {\n return this.channels.get(key);\n }\n\n list(): Array<{ key: string } & NotificationChannelConfig> {\n return Array.from(this.channels.entries()).map(([key, cfg]) => ({ key, ...cfg }));\n }\n\n has(key: string): boolean {\n return this.channels.has(key);\n }\n}\n\nexport const notificationChannelRegistry = new NotificationChannelRegistry();\nexport default NotificationChannelRegistry;\n"],"names":["NotificationChannelRegistry","key","config","cfg","notificationChannelRegistry"],"mappings":"+eAWA,MAAMA,CAA4B,CAAlC,aAAA,CACE,KAAQ,aAAe,GAAuC,CAE9D,SAASC,EAAaC,EAAyC,CAC7D,KAAK,SAAS,IAAID,EAAKC,CAAM,CAC/B,CAEA,IAAID,EAAoD,CACtD,OAAO,KAAK,SAAS,IAAIA,CAAG,CAC9B,CAEA,MAA2D,CACzD,OAAO,MAAM,KAAK,KAAK,SAAS,QAAA,CAAS,EAAE,IAAI,CAAC,CAACA,EAAKE,CAAG,KAAO,CAAE,IAAAF,EAAK,GAAGE,GAAM,CAClF,CAEA,IAAIF,EAAsB,CACxB,OAAO,KAAK,SAAS,IAAIA,CAAG,CAC9B,CACF,CAEO,MAAMG,EAA8B,IAAIJ"}
package/dist/index.d.ts CHANGED
@@ -247,6 +247,13 @@ export declare interface ConditionFieldDef {
247
247
  value: string;
248
248
  label: string;
249
249
  }>;
250
+ /**
251
+ * Declarative dynamic options — same shape as `FieldDescriptor.optionsSource`.
252
+ * `dependsOn` resolves against the OUTER form values (not the condition entry),
253
+ * so a condition column can depend on another top-level field (e.g. attributes
254
+ * scoped by `applicationUuid`).
255
+ */
256
+ optionsSource?: OptionsSource;
250
257
  /** When true, renders a FormulaInput chip editor instead of a plain <input> */
251
258
  formula?: boolean;
252
259
  }
@@ -533,6 +540,12 @@ export declare interface FieldDescriptor {
533
540
  onChange?: (value: unknown, ctx: FieldContext & {
534
541
  setFieldValue: (name: string, value: unknown) => void;
535
542
  }) => void;
543
+ /**
544
+ * Declarative dynamic options. The renderer translates this into a paged,
545
+ * cached, abortable async loader via the host's resolver registry.
546
+ * Mutually compatible with static `options`: static wins if both set.
547
+ */
548
+ optionsSource?: OptionsSource;
536
549
  [key: string]: unknown;
537
550
  }
538
551
 
@@ -583,7 +596,7 @@ declare interface FixedNode {
583
596
  deletable?: false;
584
597
  }
585
598
 
586
- declare const FlowForgeCanvas: ({ nodeRegistry, templateRegistry, initialValue, nodeTypes: consumerNodeTypes, edgeTypes: consumerEdgeTypes, onSave, readOnly, theme, messages: messageOverrides, canvasOptions, renderTriggerSelector, loadTriggerSources, renderNodePicker, renderNodeConfig, onNodeClick: onNodeClickProp, maxNodes, layoutDirection, executionRecord, onFetchWorkflow, hideHeader, workflowName, onWorkflowNameChange, onCancel, workflowStatus, workflowStatusColor, saveLabel, }: FlowForgeCanvasProps) => JSX_2.Element;
599
+ declare const FlowForgeCanvas: ({ nodeRegistry, templateRegistry, initialValue, nodeTypes: consumerNodeTypes, edgeTypes: consumerEdgeTypes, onSave, readOnly, theme, messages: messageOverrides, canvasOptions, renderTriggerSelector, loadTriggerSources, renderNodePicker, renderNodeConfig, onNodeClick: onNodeClickProp, maxNodes, layoutDirection, executionRecord, onFetchWorkflow, hideHeader, workflowName, onWorkflowNameChange, onCancel, workflowStatus, workflowStatusColor, saveLabel, optionsResolvers, }: FlowForgeCanvasProps) => JSX_2.Element;
587
600
  export { FlowForgeCanvas }
588
601
  export { FlowForgeCanvas as WorkflowCanvas }
589
602
 
@@ -685,6 +698,27 @@ export declare interface FlowForgeCanvasProps {
685
698
  workflowStatusColor?: 'gray' | 'green' | 'amber' | 'red' | string;
686
699
  /** Override the Save button label. */
687
700
  saveLabel?: string;
701
+ /**
702
+ * Host-registered map of named option resolvers. Fields in any node's
703
+ * `formSchema` may declare `optionsSource: { id, dependsOn, params }` to
704
+ * populate a select asynchronously. Transport-agnostic — the host's
705
+ * resolver can use axios, fetch, GraphQL, etc.
706
+ *
707
+ * Example:
708
+ * optionsResolvers={{
709
+ * 'app:groups': async ({ appId }, { cursor=0 }) => {
710
+ * const res = await api.get(`/groups?startIndex=${cursor}&count=50`);
711
+ * return {
712
+ * options: res.data.map(g => ({ value: g.uuid, label: g.name })),
713
+ * nextCursor: res.data.length === 50 ? cursor + 50 : undefined,
714
+ * };
715
+ * }
716
+ * }}
717
+ *
718
+ * Resolvers are cached for the session keyed by (resolverId, deps). Use
719
+ * `useOptionsResolvers().invalidate(id)` to bust a cache entry manually.
720
+ */
721
+ optionsResolvers?: OptionsResolvers;
688
722
  }
689
723
 
690
724
  export declare interface FlowForgeFieldDefinition {
@@ -914,6 +948,13 @@ declare interface FormulaProps {
914
948
  isValid: boolean;
915
949
  errors: Record<string, unknown>;
916
950
  }) => void;
951
+ /**
952
+ * Host-registered resolver map for declarative dynamic options.
953
+ * Fields with `optionsSource: { id: '...', dependsOn: ... }` look up
954
+ * their loader in this map. Transport-agnostic — use axios, fetch,
955
+ * GraphQL, anything that returns a Promise.
956
+ */
957
+ optionsResolvers?: OptionsResolvers;
917
958
  }
918
959
 
919
960
  export declare type FormulaToken = TextToken | ChipToken;
@@ -1110,6 +1151,74 @@ export declare interface ObjectFieldRendererProps {
1110
1151
 
1111
1152
  export declare const offboardingSkeleton: WorkflowState;
1112
1153
 
1154
+ /** A resolver function — transport-agnostic. */
1155
+ export declare type OptionsResolver = (deps: Record<string, unknown>, ctx: OptionsResolverContext) => Promise<OptionsResolverResult>;
1156
+
1157
+ /** Args passed to a resolver per call — cursor for pagination, input for typeahead. */
1158
+ export declare interface OptionsResolverContext {
1159
+ cursor?: unknown;
1160
+ input?: string;
1161
+ /** Full top-level form values, in case a resolver needs read-only access. */
1162
+ values?: Record<string, unknown>;
1163
+ /** AbortSignal — resolvers SHOULD honor this when their transport supports it. */
1164
+ signal?: AbortSignal;
1165
+ }
1166
+
1167
+ /** Resolver return shape — matches Pipedream's `options` contract. */
1168
+ export declare interface OptionsResolverResult {
1169
+ options: Array<{
1170
+ value: unknown;
1171
+ label: string;
1172
+ isDisabled?: boolean;
1173
+ [key: string]: unknown;
1174
+ }>;
1175
+ /** Opaque cursor returned to the next call. Omit to signal "no more pages". */
1176
+ nextCursor?: unknown;
1177
+ }
1178
+
1179
+ /**
1180
+ * Map of named resolvers — the host registers these once on the canvas / form.
1181
+ * Keys are the `optionsSource.id` strings referenced by field descriptors.
1182
+ */
1183
+ export declare type OptionsResolvers = Record<string, OptionsResolver>;
1184
+
1185
+ declare interface OptionsResolversContextValue {
1186
+ resolvers: OptionsResolvers;
1187
+ /**
1188
+ * Bust a single resolver's cache. Useful for an explicit "Refresh" button.
1189
+ * Pass undefined to clear ALL cached pages for that resolver.
1190
+ */
1191
+ invalidate: (resolverId: string, depsKey?: string) => void;
1192
+ }
1193
+
1194
+ export declare function OptionsResolversProvider({ resolvers, children }: ProviderProps): JSX_2.Element;
1195
+
1196
+ export declare interface OptionsSource {
1197
+ /** Resolver id — must match a key in the host's `optionsResolvers` map. */
1198
+ id: string;
1199
+ /**
1200
+ * Other field values this resolver depends on. Two shapes accepted:
1201
+ * - `string[]` — pass through verbatim ({ fieldA: values.fieldA, ... })
1202
+ * - `Record<arg, fieldName>` — rename parent values for the resolver
1203
+ *
1204
+ * When any dep value changes, the cache key for this field invalidates
1205
+ * and the resolver re-fires.
1206
+ */
1207
+ dependsOn?: string[] | Record<string, string>;
1208
+ /**
1209
+ * Static params merged into the deps object for every call. Use for
1210
+ * "URL template via the generic resolver" style:
1211
+ * { id: 'default', params: { url: '/groups', valueKey: 'uuid' } }
1212
+ */
1213
+ params?: Record<string, unknown>;
1214
+ /**
1215
+ * Lookup individual options by value (edit-mode hydration). When set,
1216
+ * the field calls this resolver with `{ ids: [...] }` to render labels
1217
+ * for already-selected values that aren't in the current page.
1218
+ */
1219
+ resolveValueId?: string;
1220
+ }
1221
+
1113
1222
  /**
1114
1223
  * Parse a raw backend string into an AST node array.
1115
1224
  *
@@ -1144,6 +1253,11 @@ export declare interface PathRefNode {
1144
1253
  label: string;
1145
1254
  }
1146
1255
 
1256
+ declare interface ProviderProps {
1257
+ resolvers?: OptionsResolvers;
1258
+ children: default_2.ReactNode;
1259
+ }
1260
+
1147
1261
  declare class Registry {
1148
1262
  private fields;
1149
1263
  constructor();
@@ -1444,6 +1558,32 @@ declare interface UncontrolledProps extends FormulaProps {
1444
1558
 
1445
1559
  export declare function unwrapFormula(value: string): string;
1446
1560
 
1561
+ /**
1562
+ * Returns a drop-in `loadOptions` for react-select when a field's
1563
+ * `optionsSource` is set and the host has registered a matching resolver.
1564
+ * Otherwise returns `enabled: false` and the host falls back to the
1565
+ * descriptor's static `options` (or no options).
1566
+ */
1567
+ export declare function useDynamicOptions({ source, values }: UseDynamicOptionsArgs): UseDynamicOptionsResult;
1568
+
1569
+ declare interface UseDynamicOptionsArgs {
1570
+ source: OptionsSource | undefined;
1571
+ values: Record<string, unknown>;
1572
+ }
1573
+
1574
+ declare interface UseDynamicOptionsResult {
1575
+ /** True when the host configured a usable resolver for this field. */
1576
+ enabled: boolean;
1577
+ /** Drop-in `loadOptions(inputValue) => Promise<Option[]>` for react-select. */
1578
+ loadOptions: ((input: string) => Promise<OptionsResolverResult['options']>) | undefined;
1579
+ /** Drop-in `loadValue(ids) => Promise<Option[]>` for edit-mode hydration. */
1580
+ loadValue: ((ids: unknown[]) => Promise<OptionsResolverResult['options']>) | undefined;
1581
+ /** Stable key derived from deps — feed to react-select's `key` to refresh on change. */
1582
+ depsKey: string;
1583
+ /** Manually invalidate this field's cache (e.g. for a Refresh button). */
1584
+ refresh: () => void;
1585
+ }
1586
+
1447
1587
  export declare function useFlowForm({ schema, initialValues, onSubmit, showErrorsImmediately, }: UseFlowFormOptions): FlowFormInstance;
1448
1588
 
1449
1589
  export declare interface UseFlowFormOptions {
@@ -1459,6 +1599,8 @@ export declare interface UseFlowFormOptions {
1459
1599
  showErrorsImmediately?: boolean;
1460
1600
  }
1461
1601
 
1602
+ export declare function useOptionsResolvers(): OptionsResolversContextValue;
1603
+
1462
1604
  export declare const userOnboardingSkeleton: WorkflowState;
1463
1605
 
1464
1606
  export declare function useVariablePickerContext(): VariablePickerContextValue | null;
package/dist/index.js CHANGED
@@ -1,110 +1,112 @@
1
- import { D as c, F as m, a as u, b as f, c as F, I as g, T as b, V as h, d as w, e as k, f as T, g as S, h as y, i as x, j as D, k as N, B as R, l as W, m as A, n as P, o as v, p as E, q as C, r as I, s as B, t as z, u as V, v as L, w as H, x as O, y as q, z as M, A as _ } from "./index-B74jTc2b.js";
2
- import { F as Y, S as G, a as J, u as K } from "./SchemaBuilderDrawer-CUzYWGCN.js";
1
+ import { D as c, F as u, a as m, b as F, c as g, I as f, O as h, T as b, V as k, d as w, e as T, f as S, g as y, h as x, i as R, j as D, k as N, E as v, l as P, m as W, n as A, o as E, p as C, q as I, r as O, s as B, t as z, u as V, v as L, w as H, x as q, y as M, z as _, A as j, B as Y, C as G } from "./index-y_v8Qog1.js";
2
+ import { F as K, S as Q, a as U, u as X } from "./SchemaBuilderDrawer-DlmInnSC.js";
3
3
  import "react/jsx-runtime";
4
4
  import "react";
5
5
  import "@mui/material";
6
6
  import "react-icons/md";
7
- import { NodeTypeRegistry as U, nodeTypeRegistry as X } from "./index-Dcur-XJ9.js";
8
- import { TemplateRegistry as $, templateRegistry as ee } from "./index-B6xrei80.js";
9
- import { F as se, a as re, S as oe, F as te, W as ie, b as le, c as ne, o as pe, u as de, w as ce } from "./templateSkeletons-BQQ7UKp6.js";
10
- import { d as ue } from "./messages-CO299wPN.js";
11
- import { l as Fe, s as ge } from "./bpmn-CtfWDaOY.js";
12
- import { A as he, b as we, E as ke, c as Te, F as Se, R as ye, S as xe, T as De, W as Ne, e as Re } from "./GatewayBranchEdge-F2AGJpun.js";
13
- import { b as Ae, c as Pe, d as ve, e as Ee, m as Ce, n as Ie, r as Be, s as ze, a as Ve, w as Le, f as He } from "./subWorkflowDescriptor-DYOYgBzX.js";
14
- class s {
7
+ import { NodeTypeRegistry as $, baseNodeDefaults as ee, conditionBranchDescriptor as se, defineNode as ae, endEventDescriptor as re, makeSubWorkflowDescriptor as oe, nodeTypeRegistry as te, notificationDescriptor as ie, restApiDescriptor as le, startEventDescriptor as ne, subWorkflowDescriptor as pe, webhookTriggerDescriptor as de, webhookTriggerTemplate as ce } from "./nodeRegistry.js";
8
+ import { TemplateRegistry as me, templateRegistry as Fe } from "./templateRegistry.js";
9
+ import { F as fe, a as he, S as be, F as ke, W as we, b as Te, c as Se, o as ye, u as xe, w as Re } from "./templateSkeletons-CHrd4Z5h.js";
10
+ import { d as Ne } from "./messages-CO299wPN.js";
11
+ import { l as Pe, s as We } from "./bpmn-CtfWDaOY.js";
12
+ import { A as Ee, b as Ce, E as Ie, c as Oe, F as Be, R as ze, S as Ve, T as Le, W as He, e as qe } from "./GatewayBranchEdge-CrgczPYJ.js";
13
+ class a {
15
14
  constructor() {
16
15
  this.channels = /* @__PURE__ */ new Map();
17
16
  }
18
- register(e, a) {
19
- this.channels.set(e, a);
17
+ register(e, s) {
18
+ this.channels.set(e, s);
20
19
  }
21
20
  get(e) {
22
21
  return this.channels.get(e);
23
22
  }
24
23
  list() {
25
- return Array.from(this.channels.entries()).map(([e, a]) => ({ key: e, ...a }));
24
+ return Array.from(this.channels.entries()).map(([e, s]) => ({ key: e, ...s }));
26
25
  }
27
26
  has(e) {
28
27
  return this.channels.has(e);
29
28
  }
30
29
  }
31
- const n = new s();
30
+ const n = new a();
32
31
  export {
33
- he as ActionNode,
34
- we as ApprovalNode,
32
+ Ee as ActionNode,
33
+ Ce as ApprovalNode,
35
34
  c as DynamicFormRenderer,
36
- ke as EdgeWithPlusLabel,
37
- Te as EndNode,
38
- m as FF,
39
- Y as FIELD_TYPE_OPTIONS,
40
- Se as FilterNode,
41
- se as FlowForgeCanvas,
42
- re as FlowForgeHeader,
43
- u as FlowForgeRegistry,
44
- f as FlowForm,
45
- F as FormulaInput,
46
- g as InfiniteSelectField,
47
- U as NodeTypeRegistry,
48
- ye as RestApiNode,
49
- G as SchemaBuilder,
50
- J as SchemaBuilderDrawer,
51
- xe as StartNode,
52
- oe as SubWorkflowPreviewDrawer,
35
+ Ie as EdgeWithPlusLabel,
36
+ Oe as EndNode,
37
+ u as FF,
38
+ K as FIELD_TYPE_OPTIONS,
39
+ Be as FilterNode,
40
+ fe as FlowForgeCanvas,
41
+ he as FlowForgeHeader,
42
+ m as FlowForgeRegistry,
43
+ F as FlowForm,
44
+ g as FormulaInput,
45
+ f as InfiniteSelectField,
46
+ $ as NodeTypeRegistry,
47
+ h as OptionsResolversProvider,
48
+ ze as RestApiNode,
49
+ Q as SchemaBuilder,
50
+ U as SchemaBuilderDrawer,
51
+ Ve as StartNode,
52
+ be as SubWorkflowPreviewDrawer,
53
53
  b as TablePickerField,
54
- $ as TemplateRegistry,
55
- De as TriggerNode,
56
- h as VariablePicker,
54
+ me as TemplateRegistry,
55
+ Le as TriggerNode,
56
+ k as VariablePicker,
57
57
  w as VariablePickerProvider,
58
- Ne as WebhookTriggerNode,
59
- te as WorkflowCanvas,
60
- ie as WorkflowExecutionHistory,
61
- le as WorkflowTemplateLibrary,
62
- ne as accessRequestSkeleton,
63
- k as astHasRefs,
64
- T as astToTokens,
65
- Ae as baseNodeDefaults,
66
- S as buildEvaluationPayload,
67
- y as buildFieldConfig,
68
- x as buildFormulaPath,
58
+ He as WebhookTriggerNode,
59
+ ke as WorkflowCanvas,
60
+ we as WorkflowExecutionHistory,
61
+ Te as WorkflowTemplateLibrary,
62
+ Se as accessRequestSkeleton,
63
+ T as astHasRefs,
64
+ S as astToTokens,
65
+ ee as baseNodeDefaults,
66
+ y as buildEvaluationPayload,
67
+ x as buildFieldConfig,
68
+ R as buildFormulaPath,
69
69
  D as buildSelectStyles,
70
70
  N as buildValidationSchema,
71
- Re as builtInNodeTypes,
72
- Pe as conditionBranchDescriptor,
73
- R as dataSourceRegistry,
74
- ue as defaultFlowForgeMessages,
75
- ve as defineNode,
76
- Ee as endEventDescriptor,
77
- W as errorTextStyle,
78
- A as extractLabel,
79
- P as fieldRegistry,
80
- v as hasFormulaTokens,
81
- E as helperTextStyle,
82
- C as inputStyle,
83
- I as isFormula,
84
- Fe as loadWorkflowFromBpmn,
85
- Ce as makeSubWorkflowDescriptor,
86
- X as nodeTypeRegistry,
71
+ qe as builtInNodeTypes,
72
+ se as conditionBranchDescriptor,
73
+ v as dataSourceRegistry,
74
+ Ne as defaultFlowForgeMessages,
75
+ ae as defineNode,
76
+ re as endEventDescriptor,
77
+ P as errorTextStyle,
78
+ W as extractLabel,
79
+ A as fieldRegistry,
80
+ E as hasFormulaTokens,
81
+ C as helperTextStyle,
82
+ I as inputStyle,
83
+ O as isFormula,
84
+ Pe as loadWorkflowFromBpmn,
85
+ oe as makeSubWorkflowDescriptor,
86
+ te as nodeTypeRegistry,
87
87
  n as notificationChannelRegistry,
88
- Ie as notificationDescriptor,
89
- pe as offboardingSkeleton,
88
+ ie as notificationDescriptor,
89
+ ye as offboardingSkeleton,
90
90
  B as parseToAST,
91
- Be as restApiDescriptor,
92
- ge as saveWorkflowToBpmn,
91
+ le as restApiDescriptor,
92
+ We as saveWorkflowToBpmn,
93
93
  z as serializeAST,
94
94
  V as serializeASTAsConfig,
95
95
  L as serializeConditionExpressions,
96
- ze as startEventDescriptor,
96
+ ne as startEventDescriptor,
97
97
  H as stripFormulaTokens,
98
- Ve as subWorkflowDescriptor,
99
- ee as templateRegistry,
100
- O as tokenize,
101
- q as unwrapFormula,
102
- K as useFlowForm,
103
- M as useVariablePickerContext,
104
- de as userOnboardingSkeleton,
105
- ce as webhookIntegrationSkeleton,
106
- Le as webhookTriggerDescriptor,
107
- He as webhookTriggerTemplate,
108
- _ as wrapFormula
98
+ pe as subWorkflowDescriptor,
99
+ Fe as templateRegistry,
100
+ q as tokenize,
101
+ M as unwrapFormula,
102
+ _ as useDynamicOptions,
103
+ X as useFlowForm,
104
+ j as useOptionsResolvers,
105
+ Y as useVariablePickerContext,
106
+ xe as userOnboardingSkeleton,
107
+ Re as webhookIntegrationSkeleton,
108
+ de as webhookTriggerDescriptor,
109
+ ce as webhookTriggerTemplate,
110
+ G as wrapFormula
109
111
  };
110
112
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../src/notificationChannelRegistry/index.ts"],"sourcesContent":["export interface NotificationChannelOption {\n value: string;\n label: string;\n}\n\nexport interface NotificationChannelConfig {\n label: string;\n /** Fetch recipients/channels for this notification channel at runtime */\n fetchRecipients?: () => Promise<NotificationChannelOption[]>;\n}\n\nclass NotificationChannelRegistry {\n private channels = new Map<string, NotificationChannelConfig>();\n\n register(key: string, config: NotificationChannelConfig): void {\n this.channels.set(key, config);\n }\n\n get(key: string): NotificationChannelConfig | undefined {\n return this.channels.get(key);\n }\n\n list(): Array<{ key: string } & NotificationChannelConfig> {\n return Array.from(this.channels.entries()).map(([key, cfg]) => ({ key, ...cfg }));\n }\n\n has(key: string): boolean {\n return this.channels.has(key);\n }\n}\n\nexport const notificationChannelRegistry = new NotificationChannelRegistry();\nexport default NotificationChannelRegistry;\n"],"names":["NotificationChannelRegistry","key","config","cfg","notificationChannelRegistry"],"mappings":";;;;;;;;;;;;;AAWA,MAAMA,EAA4B;AAAA,EAAlC,cAAA;AACE,SAAQ,+BAAe,IAAA;AAAA,EAAuC;AAAA,EAE9D,SAASC,GAAaC,GAAyC;AAC7D,SAAK,SAAS,IAAID,GAAKC,CAAM;AAAA,EAC/B;AAAA,EAEA,IAAID,GAAoD;AACtD,WAAO,KAAK,SAAS,IAAIA,CAAG;AAAA,EAC9B;AAAA,EAEA,OAA2D;AACzD,WAAO,MAAM,KAAK,KAAK,SAAS,QAAA,CAAS,EAAE,IAAI,CAAC,CAACA,GAAKE,CAAG,OAAO,EAAE,KAAAF,GAAK,GAAGE,IAAM;AAAA,EAClF;AAAA,EAEA,IAAIF,GAAsB;AACxB,WAAO,KAAK,SAAS,IAAIA,CAAG;AAAA,EAC9B;AACF;AAEO,MAAMG,IAA8B,IAAIJ,EAAA;"}
1
+ {"version":3,"file":"index.js","sources":["../src/notificationChannelRegistry/index.ts"],"sourcesContent":["export interface NotificationChannelOption {\n value: string;\n label: string;\n}\n\nexport interface NotificationChannelConfig {\n label: string;\n /** Fetch recipients/channels for this notification channel at runtime */\n fetchRecipients?: () => Promise<NotificationChannelOption[]>;\n}\n\nclass NotificationChannelRegistry {\n private channels = new Map<string, NotificationChannelConfig>();\n\n register(key: string, config: NotificationChannelConfig): void {\n this.channels.set(key, config);\n }\n\n get(key: string): NotificationChannelConfig | undefined {\n return this.channels.get(key);\n }\n\n list(): Array<{ key: string } & NotificationChannelConfig> {\n return Array.from(this.channels.entries()).map(([key, cfg]) => ({ key, ...cfg }));\n }\n\n has(key: string): boolean {\n return this.channels.has(key);\n }\n}\n\nexport const notificationChannelRegistry = new NotificationChannelRegistry();\nexport default NotificationChannelRegistry;\n"],"names":["NotificationChannelRegistry","key","config","cfg","notificationChannelRegistry"],"mappings":";;;;;;;;;;;;AAWA,MAAMA,EAA4B;AAAA,EAAlC,cAAA;AACE,SAAQ,+BAAe,IAAA;AAAA,EAAuC;AAAA,EAE9D,SAASC,GAAaC,GAAyC;AAC7D,SAAK,SAAS,IAAID,GAAKC,CAAM;AAAA,EAC/B;AAAA,EAEA,IAAID,GAAoD;AACtD,WAAO,KAAK,SAAS,IAAIA,CAAG;AAAA,EAC9B;AAAA,EAEA,OAA2D;AACzD,WAAO,MAAM,KAAK,KAAK,SAAS,QAAA,CAAS,EAAE,IAAI,CAAC,CAACA,GAAKE,CAAG,OAAO,EAAE,KAAAF,GAAK,GAAGE,IAAM;AAAA,EAClF;AAAA,EAEA,IAAIF,GAAsB;AACxB,WAAO,KAAK,SAAS,IAAIA,CAAG;AAAA,EAC9B;AACF;AAEO,MAAMG,IAA8B,IAAIJ,EAAA;"}
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./subWorkflowDescriptor-JDKi2INh.js");class o{constructor(){this.descriptors=new Map}register(r){return this.descriptors.set(r.type,r),this}forType(r){return this.descriptors.get(r)}forId(r){for(const t of this.descriptors.values())if(t.matches(r))return t}list(){return[...this.descriptors.values()]}}const s=new o;exports.baseNodeDefaults=e.baseNodeDefaults;exports.conditionBranchDescriptor=e.conditionBranchDescriptor;exports.defineNode=e.defineNode;exports.endEventDescriptor=e.endEventDescriptor;exports.makeSubWorkflowDescriptor=e.makeSubWorkflowDescriptor;exports.notificationDescriptor=e.notificationDescriptor;exports.restApiDescriptor=e.restApiDescriptor;exports.startEventDescriptor=e.startEventDescriptor;exports.subWorkflowDescriptor=e.subWorkflowDescriptor;exports.webhookTriggerDescriptor=e.webhookTriggerDescriptor;exports.webhookTriggerTemplate=e.webhookTriggerTemplate;exports.NodeTypeRegistry=o;exports.nodeTypeRegistry=s;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react"),r=require("react-icons/md"),d=require("./canvasTokens-gKNYrPl4.js"),s={formSchema:[],bpmnEntry:e=>e,bpmnExit:e=>e,emitBpmnElements:e=>[{id:e,$type:"bpmn:Task"}]};function o(e){return{...s,...e}}const u=o({type:"startEvent",label:"Start",icon:a.createElement(r.MdPlayCircleOutline,{size:18,color:"#616161"}),matches:e=>e==="start",reactFlowType:"startNode",emitBpmnElements:e=>[{id:e,$type:"bpmn:StartEvent"}],maxPerWorkflow:1}),b=o({type:"endEvent",label:"End",icon:a.createElement(r.MdStopCircle,{size:18,color:"#616161"}),matches:e=>e==="end"||e.startsWith("end-"),reactFlowType:"endNode",emitBpmnElements:e=>[{id:e,$type:"bpmn:EndEvent"}]}),h=o({type:"restApi",label:"REST API Call",icon:a.createElement(r.MdHttp,{size:18,color:"#546e7a"}),matches:e=>e.startsWith("restApi-"),reactFlowType:"restApiNode",formSchema:[{id:"method",type:"select",label:"HTTP Method",required:!0,options:[{label:"GET",value:"GET"},{label:"POST",value:"POST"},{label:"PUT",value:"PUT"},{label:"PATCH",value:"PATCH"},{label:"DELETE",value:"DELETE"}]},{id:"url",type:"text",label:"URL",required:!0,placeholder:"https://api.example.com/endpoint",formulaEnabled:!0},{id:"headers",type:"key-value",label:"Request Headers",placeholder:"Add headers..."},{id:"queryParams",type:"key-value",label:"Query Parameters",shouldHide:({values:e})=>e.method!=="GET"&&e.method!=="DELETE"},{id:"body",type:"json-editor",label:"Request Body (JSON)",shouldHide:({values:e})=>e.method==="GET"||e.method==="DELETE"},{id:"responseMapping",type:"array",label:"Map Response Fields to Variables",children:[{id:"jsonPath",type:"text",label:"JSON Path",placeholder:"$.data.userId",required:!0},{id:"variableName",type:"text",label:"Variable Name",placeholder:"userId",required:!0}]},{id:"timeoutMs",type:"number",label:"Timeout (ms)",placeholder:"5000"},{id:"continueOnError",type:"toggle",label:"Continue workflow on error"}],bpmnEntry:e=>`REST API Call: ${e}`,bpmnExit:e=>`End REST API Call: ${e}`,emitBpmnElements:(e,t)=>{const l=t;return[{id:e,$type:"bpmn:ServiceTask",name:`${l.method??"HTTP"} ${l.url??""}`.trim()}]}}),m=o({type:"notification",label:"Send Notification",icon:a.createElement(r.MdNotifications,{size:18,color:"#7b1fa2"}),matches:e=>e.startsWith("notification-"),reactFlowType:"notificationNode",formSchema:[{id:"channel",type:"descriptive-select",label:"Notification Channel",required:!0,options:[{value:"email",label:"Email",description:"Send via SMTP or email provider"},{value:"slack",label:"Slack",description:"Post to a Slack channel or DM"},{value:"teams",label:"Microsoft Teams",description:"Post to a Teams channel or chat"},{value:"sms",label:"SMS",description:"Send a text message"},{value:"in-app",label:"In-App",description:"miniOrange notification center"},{value:"webhook",label:"Webhook",description:"POST to an external URL"}]},{id:"emailTo",type:"tags",label:"To",placeholder:"Add email address...",required:!0,shouldHide:({values:e})=>e.channel!=="email",formulaEnabled:!0},{id:"emailCc",type:"tags",label:"CC",placeholder:"Add email address...",shouldHide:({values:e})=>e.channel!=="email"},{id:"emailSubject",type:"text",label:"Subject",required:!0,formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="email"},{id:"emailBody",type:"rich-text",label:"Body",required:!0,shouldHide:({values:e})=>e.channel!=="email"},{id:"slackChannel",type:"text",label:"Channel / DM",required:!0,placeholder:"#general or @username",formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="slack"},{id:"slackMessage",type:"textarea",label:"Message",required:!0,formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="slack"},{id:"teamsWebhookUrl",type:"text",label:"Incoming Webhook URL",required:!0,placeholder:"https://...",shouldHide:({values:e})=>e.channel!=="teams"},{id:"teamsMessage",type:"textarea",label:"Message",required:!0,formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="teams"},{id:"smsTo",type:"text",label:"Phone Number",required:!0,placeholder:"+1234567890",formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="sms"},{id:"smsBody",type:"textarea",label:"Message",required:!0,formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="sms"},{id:"inAppRecipient",type:"text",label:"Recipient (User ID or Username)",required:!0,formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="in-app"},{id:"inAppTitle",type:"text",label:"Title",required:!0,formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="in-app"},{id:"inAppBody",type:"textarea",label:"Message",required:!0,formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="in-app"},{id:"webhookUrl",type:"text",label:"Webhook URL",required:!0,placeholder:"https://...",formulaEnabled:!0,shouldHide:({values:e})=>e.channel!=="webhook"},{id:"webhookPayload",type:"json-editor",label:"Payload (JSON)",shouldHide:({values:e})=>e.channel!=="webhook"},{id:"sendOnFailure",type:"toggle",label:"Also send notification on workflow failure"},{id:"deduplicationKey",type:"text",label:"Deduplication Key",placeholder:"Optional — prevents duplicate sends",formulaEnabled:!0}],bpmnEntry:e=>`Send Notification: ${e}`,bpmnExit:e=>`End Notification: ${e}`,emitBpmnElements:(e,t)=>[{id:e,$type:"bpmn:SendTask",name:`Notify via ${t.channel??"channel"}`}]}),y=[{label:"equals (=)",value:"eq"},{label:"not equals (≠)",value:"neq"},{label:"greater than (>)",value:"gt"},{label:"greater or equal (≥)",value:"gte"},{label:"less than (<)",value:"lt"},{label:"less or equal (≤)",value:"lte"},{label:"contains",value:"contains"},{label:"starts with",value:"startsWith"},{label:"ends with",value:"endsWith"},{label:"is empty",value:"isEmpty"},{label:"is not empty",value:"isNotEmpty"}],E=o({type:"conditionBranch",label:"Condition Branch",icon:a.createElement(r.MdCallSplit,{size:18,color:"#512da8"}),matches:e=>e.startsWith("conditionBranch-"),reactFlowType:"conditionBranchNode",branchLabels:{branch1:"IF · Branch 1",branch2:"ELSE IF · Branch 2",default:"ELSE"},formSchema:[{id:"title",type:"text",label:"Node Label",placeholder:"e.g. Route by User Role"},{id:"branchConfigs",type:"array",label:"Branches",required:!0,children:[{id:"kind",type:"select",label:"Branch Type",required:!0,options:[{label:"IF",value:"if"},{label:"ELSE IF",value:"elseif"},{label:"ELSE",value:"else"}],placeholder:"elseif"},{id:"key",type:"text",label:"Branch Key",required:!0,placeholder:"e.g. admin (no spaces)"},{id:"label",type:"text",label:"Branch Label",required:!0,placeholder:"e.g. Admin Users"},{id:"conditions",type:"array",label:"Conditions",shouldHide:({values:e})=>e.kind==="else",children:[{id:"field",type:"text",label:"Field / Variable",required:!0,placeholder:"e.g. user.role",formulaEnabled:!0},{id:"operator",type:"select",label:"Operator",required:!0,options:y},{id:"value",type:"text",label:"Value",placeholder:"e.g. admin",formulaEnabled:!0,shouldHide:({values:e})=>e.operator==="isEmpty"||e.operator==="isNotEmpty"},{id:"logicalOperator",type:"select",label:"Combine with next",options:[{label:"AND",value:"AND"},{label:"OR",value:"OR"}]}]}]},{id:"defaultBranch",type:"text",label:"Default Branch Key (fallback if no condition matches)",placeholder:"e.g. default"}],bpmnEntry:e=>`Condition Branch: ${e}`,bpmnExit:e=>`End Condition Branch: ${e}`,emitBpmnElements:(e,t)=>{const l=t,i=l.branchConfigs??[];return[{id:e,$type:"bpmn:ExclusiveGateway",name:l.title??"Condition Branch"},...i.map(n=>({id:`${e}-${n.key}`,$type:"bpmn:SequenceFlow",name:n.label}))]}}),f=o({type:"webhookTrigger",label:"Webhook Trigger",icon:a.createElement(r.MdWebhook,{size:d.NODE_DESCRIPTOR_ICON_SIZE,color:"#1565c0"}),matches:e=>e.startsWith("webhookTrigger-"),reactFlowType:"webhookTriggerNode",formSchema:[{id:"endpointUrl",type:"text",label:"Endpoint URL",disabled:!0,placeholder:"Generated after saving"},{id:"authMethod",type:"select",label:"Authentication",required:!0,options:[{label:"None",value:"none"},{label:"API Key",value:"api-key"},{label:"HMAC Signature",value:"hmac"}]},{id:"apiKeyHeader",type:"text",label:"API Key Header Name",placeholder:"e.g. X-API-Key",shouldHide:({values:e})=>e.authMethod!=="api-key"},{id:"hmacSecret",type:"text",label:"HMAC Secret",placeholder:"Shared secret for signature verification",shouldHide:({values:e})=>e.authMethod!=="hmac"},{id:"payloadDescription",type:"textarea",label:"Expected Payload Description",placeholder:"Describe the expected JSON payload fields..."}],bpmnEntry:e=>`Webhook Trigger: ${e}`,bpmnExit:e=>`End Webhook Trigger: ${e}`,emitBpmnElements:e=>[{id:e,$type:"bpmn:StartEvent",name:"Webhook Trigger"}]}),g={triggerKey:"WEBHOOK_TRIGGER",label:"Incoming Webhook",description:"Start this workflow when an HTTP POST is received at a generated endpoint.",triggerCategory:"webhook",icon:a.createElement(r.MdWebhook,{size:d.NODE_DESCRIPTOR_ICON_SIZE,color:"#1565c0"})};function p(e={}){return o({type:"subWorkflow",label:"Sub-Workflow",icon:a.createElement(r.MdAccountTree,{size:18,color:"#00695c"}),matches:t=>t.startsWith("subWorkflow-"),reactFlowType:"subWorkflowNode",formSchema:[{id:"workflowId",type:"select",label:"Workflow to Call",required:!0,placeholder:"Select a workflow...",...e.fetchWorkflowOptions?{fetchOptions:e.fetchWorkflowOptions}:{options:[]}},{id:"workflowLabel",type:"text",label:"Display Name (optional)",placeholder:"Override display name shown on canvas"},{id:"inputMapping",type:"key-value",label:"Input Mapping",placeholder:"Map parent variables → sub-workflow inputs",formulaEnabled:!0},{id:"outputMapping",type:"key-value",label:"Output Mapping",placeholder:"Map sub-workflow outputs → parent variables"},{id:"waitForCompletion",type:"toggle",label:"Wait for sub-workflow to complete before continuing"},{id:"continueOnError",type:"toggle",label:"Continue parent workflow if sub-workflow fails"}],bpmnEntry:t=>`Sub-Workflow Call: ${t}`,bpmnExit:t=>`End Sub-Workflow Call: ${t}`,emitBpmnElements:(t,l)=>{const i=l;return[{id:t,$type:"bpmn:CallActivity",name:i.workflowLabel||i.workflowId||"Sub-Workflow",calledElement:i.workflowId}]}})}const k=p();class c{constructor(){this.descriptors=new Map}register(t){return this.descriptors.set(t.type,t),this}forType(t){return this.descriptors.get(t)}forId(t){for(const l of this.descriptors.values())if(l.matches(t))return l}list(){return[...this.descriptors.values()]}}const w=new c;exports.NodeTypeRegistry=c;exports.baseNodeDefaults=s;exports.conditionBranchDescriptor=E;exports.defineNode=o;exports.endEventDescriptor=b;exports.makeSubWorkflowDescriptor=p;exports.nodeTypeRegistry=w;exports.notificationDescriptor=m;exports.restApiDescriptor=h;exports.startEventDescriptor=u;exports.subWorkflowDescriptor=k;exports.webhookTriggerDescriptor=f;exports.webhookTriggerTemplate=g;
2
2
  //# sourceMappingURL=nodeRegistry.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"nodeRegistry.cjs","sources":["../src/nodeRegistry/index.ts"],"sourcesContent":["import { NodeDescriptor } from '../WorkflowCanvas/types';\n\nexport class NodeTypeRegistry {\n private descriptors = new Map<string, NodeDescriptor>();\n\n register(descriptor: NodeDescriptor): this {\n this.descriptors.set(descriptor.type, descriptor);\n return this;\n }\n\n forType(type: string): NodeDescriptor | undefined {\n return this.descriptors.get(type);\n }\n\n forId(id: string): NodeDescriptor | undefined {\n for (const d of this.descriptors.values()) {\n if (d.matches(id)) return d;\n }\n return undefined;\n }\n\n list(): NodeDescriptor[] {\n return [...this.descriptors.values()];\n }\n}\n\nexport const nodeTypeRegistry = new NodeTypeRegistry();\nexport type { NodeDescriptor };\n\n// ── Base node + factory ────────────────────────────────────────────────────\nexport { defineNode, baseNodeDefaults } from './defineNode';\n\n// ── Built-in node descriptors ──────────────────────────────────────────────\nexport { startEventDescriptor } from './descriptors/startEventDescriptor';\nexport { endEventDescriptor } from './descriptors/endEventDescriptor';\nexport { restApiDescriptor } from './descriptors/restApiDescriptor';\nexport { notificationDescriptor } from './descriptors/notificationDescriptor';\nexport { conditionBranchDescriptor } from './descriptors/conditionBranchDescriptor';\nexport { webhookTriggerDescriptor, webhookTriggerTemplate } from './descriptors/webhookDescriptors';\nexport { subWorkflowDescriptor, makeSubWorkflowDescriptor } from './descriptors/subWorkflowDescriptor';\nexport type { SubWorkflowDescriptorOptions } from './descriptors/subWorkflowDescriptor';\n"],"names":["NodeTypeRegistry","descriptor","type","id","d","nodeTypeRegistry"],"mappings":"uIAEO,MAAMA,CAAiB,CAAvB,aAAA,CACL,KAAQ,gBAAkB,GAA4B,CAEtD,SAASC,EAAkC,CACzC,YAAK,YAAY,IAAIA,EAAW,KAAMA,CAAU,EACzC,IACT,CAEA,QAAQC,EAA0C,CAChD,OAAO,KAAK,YAAY,IAAIA,CAAI,CAClC,CAEA,MAAMC,EAAwC,CAC5C,UAAWC,KAAK,KAAK,YAAY,OAAA,EAC/B,GAAIA,EAAE,QAAQD,CAAE,EAAG,OAAOC,CAG9B,CAEA,MAAyB,CACvB,MAAO,CAAC,GAAG,KAAK,YAAY,QAAQ,CACtC,CACF,CAEO,MAAMC,EAAmB,IAAIL"}
1
+ {"version":3,"file":"nodeRegistry.cjs","sources":["../src/nodeRegistry/defineNode.ts","../src/nodeRegistry/descriptors/startEventDescriptor.ts","../src/nodeRegistry/descriptors/endEventDescriptor.ts","../src/nodeRegistry/descriptors/restApiDescriptor.ts","../src/nodeRegistry/descriptors/notificationDescriptor.ts","../src/nodeRegistry/descriptors/conditionBranchDescriptor.ts","../src/nodeRegistry/descriptors/webhookDescriptors.ts","../src/nodeRegistry/descriptors/subWorkflowDescriptor.ts","../src/nodeRegistry/index.ts"],"sourcesContent":["import { NodeDescriptor } from '../WorkflowCanvas/types';\n\n/**\n * Base defaults shared by every node descriptor. A new node only has to specify\n * what makes it different — these fill in the rest.\n *\n * - `formSchema: []` → no config form unless the node defines one\n * - `bpmnEntry` / `bpmnExit` → incoming/outgoing flow connects to the node id itself\n * - `emitBpmnElements` → a single generic bpmn:Task; override for real output\n */\nexport const baseNodeDefaults: Pick<\n NodeDescriptor,\n 'formSchema' | 'bpmnEntry' | 'bpmnExit' | 'emitBpmnElements'\n> = {\n formSchema: [],\n bpmnEntry: (id) => id,\n bpmnExit: (id) => id,\n emitBpmnElements: (id) => [{ id, $type: 'bpmn:Task' }],\n};\n\n/** The fields every node MUST provide — there is no sensible default for these. */\ntype RequiredNodeFields = Pick<NodeDescriptor, 'type' | 'label' | 'matches' | 'reactFlowType'>;\n\n/**\n * Build a node descriptor on top of {@link baseNodeDefaults}.\n *\n * Supply the four required identity fields plus only the behaviour you want to\n * override. Everything else inherits the base.\n *\n * export const startEventDescriptor = defineNode({\n * type: 'startEvent',\n * label: 'Start',\n * matches: (id) => id === 'start',\n * reactFlowType: 'startNode',\n * emitBpmnElements: (id) => [{ id, $type: 'bpmn:StartEvent' }], // override\n * });\n */\nexport function defineNode(\n overrides: RequiredNodeFields & Partial<NodeDescriptor>,\n): NodeDescriptor {\n return { ...baseNodeDefaults, ...overrides };\n}\n","import React from 'react';\nimport { MdPlayCircleOutline } from 'react-icons/md';\nimport { defineNode } from '../defineNode';\n\n/**\n * Start event — a fixed skeleton node with no user-editable form.\n * The canvas seeds it as the literal slot id `'start'` (see buildInitialSlots\n * in WorkflowCanvas.tsx). This descriptor exists so the registry can resolve\n * that id via `forId('start')` and emit it during descriptor-driven BPMN save.\n *\n * Inherits formSchema (none) and bpmnEntry/bpmnExit from the base node.\n */\nexport const startEventDescriptor = defineNode({\n type: 'startEvent',\n label: 'Start',\n icon: React.createElement(MdPlayCircleOutline, { size: 18, color: '#616161' }),\n matches: (id) => id === 'start',\n reactFlowType: 'startNode',\n emitBpmnElements: (id) => [{ id, $type: 'bpmn:StartEvent' }],\n maxPerWorkflow: 1,\n});\n","import React from 'react';\nimport { MdStopCircle } from 'react-icons/md';\nimport { defineNode } from '../defineNode';\n\n/**\n * End event — a fixed skeleton node with no user-editable form.\n * The canvas seeds the main-spine end as the literal slot id `'end'`, and one\n * end per branch as `'end-${filterId}-${branch}'` (see WorkflowCanvas.tsx).\n * `matches` must cover both shapes so every terminal node resolves via `forId`\n * during descriptor-driven BPMN load — otherwise branch ends get skipped.\n *\n * Inherits formSchema (none) and bpmnEntry/bpmnExit from the base node.\n */\nexport const endEventDescriptor = defineNode({\n type: 'endEvent',\n label: 'End',\n icon: React.createElement(MdStopCircle, { size: 18, color: '#616161' }),\n matches: (id) => id === 'end' || id.startsWith('end-'),\n reactFlowType: 'endNode',\n emitBpmnElements: (id) => [{ id, $type: 'bpmn:EndEvent' }],\n});\n","import React from 'react';\nimport { MdHttp } from 'react-icons/md';\nimport { defineNode } from '../defineNode';\n\nexport const restApiDescriptor = defineNode({\n type: 'restApi',\n label: 'REST API Call',\n icon: React.createElement(MdHttp, { size: 18, color: '#546e7a' }),\n matches: (id) => id.startsWith('restApi-'),\n reactFlowType: 'restApiNode',\n formSchema: [\n {\n id: 'method',\n type: 'select',\n label: 'HTTP Method',\n required: true,\n options: [\n { label: 'GET', value: 'GET' },\n { label: 'POST', value: 'POST' },\n { label: 'PUT', value: 'PUT' },\n { label: 'PATCH', value: 'PATCH' },\n { label: 'DELETE', value: 'DELETE' },\n ],\n },\n {\n id: 'url',\n type: 'text',\n label: 'URL',\n required: true,\n placeholder: 'https://api.example.com/endpoint',\n formulaEnabled: true,\n },\n {\n id: 'headers',\n type: 'key-value',\n label: 'Request Headers',\n placeholder: 'Add headers...',\n },\n {\n id: 'queryParams',\n type: 'key-value',\n label: 'Query Parameters',\n shouldHide: ({ values }: { values: Record<string, unknown> }) =>\n values.method !== 'GET' && values.method !== 'DELETE',\n },\n {\n id: 'body',\n type: 'json-editor',\n label: 'Request Body (JSON)',\n shouldHide: ({ values }: { values: Record<string, unknown> }) =>\n values.method === 'GET' || values.method === 'DELETE',\n },\n {\n id: 'responseMapping',\n type: 'array',\n label: 'Map Response Fields to Variables',\n children: [\n {\n id: 'jsonPath',\n type: 'text',\n label: 'JSON Path',\n placeholder: '$.data.userId',\n required: true,\n },\n {\n id: 'variableName',\n type: 'text',\n label: 'Variable Name',\n placeholder: 'userId',\n required: true,\n },\n ],\n },\n {\n id: 'timeoutMs',\n type: 'number',\n label: 'Timeout (ms)',\n placeholder: '5000',\n },\n {\n id: 'continueOnError',\n type: 'toggle',\n label: 'Continue workflow on error',\n },\n ],\n bpmnEntry: (id) => `REST API Call: ${id}`,\n bpmnExit: (id) => `End REST API Call: ${id}`,\n emitBpmnElements: (id, data) => {\n const d = data as Record<string, unknown>;\n return [{\n id,\n $type: 'bpmn:ServiceTask',\n name: `${d.method ?? 'HTTP'} ${d.url ?? ''}`.trim(),\n }];\n },\n});\n","import React from 'react';\nimport { MdNotifications } from 'react-icons/md';\nimport { defineNode } from '../defineNode';\n\nexport const notificationDescriptor = defineNode({\n type: 'notification',\n label: 'Send Notification',\n icon: React.createElement(MdNotifications, { size: 18, color: '#7b1fa2' }),\n matches: (id) => id.startsWith('notification-'),\n reactFlowType: 'notificationNode',\n formSchema: [\n {\n id: 'channel',\n type: 'descriptive-select',\n label: 'Notification Channel',\n required: true,\n options: [\n { value: 'email', label: 'Email', description: 'Send via SMTP or email provider' },\n { value: 'slack', label: 'Slack', description: 'Post to a Slack channel or DM' },\n { value: 'teams', label: 'Microsoft Teams', description: 'Post to a Teams channel or chat' },\n { value: 'sms', label: 'SMS', description: 'Send a text message' },\n { value: 'in-app', label: 'In-App', description: 'miniOrange notification center' },\n { value: 'webhook', label: 'Webhook', description: 'POST to an external URL' },\n ],\n },\n\n // ── Email fields ──────────────────────────────────────────────────────────\n {\n id: 'emailTo',\n type: 'tags',\n label: 'To',\n placeholder: 'Add email address...',\n required: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'email',\n formulaEnabled: true,\n },\n {\n id: 'emailCc',\n type: 'tags',\n label: 'CC',\n placeholder: 'Add email address...',\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'email',\n },\n {\n id: 'emailSubject',\n type: 'text',\n label: 'Subject',\n required: true,\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'email',\n },\n {\n id: 'emailBody',\n type: 'rich-text',\n label: 'Body',\n required: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'email',\n },\n\n // ── Slack fields ──────────────────────────────────────────────────────────\n {\n id: 'slackChannel',\n type: 'text',\n label: 'Channel / DM',\n required: true,\n placeholder: '#general or @username',\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'slack',\n },\n {\n id: 'slackMessage',\n type: 'textarea',\n label: 'Message',\n required: true,\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'slack',\n },\n\n // ── Teams fields ──────────────────────────────────────────────────────────\n {\n id: 'teamsWebhookUrl',\n type: 'text',\n label: 'Incoming Webhook URL',\n required: true,\n placeholder: 'https://...',\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'teams',\n },\n {\n id: 'teamsMessage',\n type: 'textarea',\n label: 'Message',\n required: true,\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'teams',\n },\n\n // ── SMS fields ────────────────────────────────────────────────────────────\n {\n id: 'smsTo',\n type: 'text',\n label: 'Phone Number',\n required: true,\n placeholder: '+1234567890',\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'sms',\n },\n {\n id: 'smsBody',\n type: 'textarea',\n label: 'Message',\n required: true,\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'sms',\n },\n\n // ── In-App fields ─────────────────────────────────────────────────────────\n {\n id: 'inAppRecipient',\n type: 'text',\n label: 'Recipient (User ID or Username)',\n required: true,\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'in-app',\n },\n {\n id: 'inAppTitle',\n type: 'text',\n label: 'Title',\n required: true,\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'in-app',\n },\n {\n id: 'inAppBody',\n type: 'textarea',\n label: 'Message',\n required: true,\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'in-app',\n },\n\n // ── Webhook fields ────────────────────────────────────────────────────────\n {\n id: 'webhookUrl',\n type: 'text',\n label: 'Webhook URL',\n required: true,\n placeholder: 'https://...',\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'webhook',\n },\n {\n id: 'webhookPayload',\n type: 'json-editor',\n label: 'Payload (JSON)',\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.channel !== 'webhook',\n },\n\n // ── Shared options ────────────────────────────────────────────────────────\n {\n id: 'sendOnFailure',\n type: 'toggle',\n label: 'Also send notification on workflow failure',\n },\n {\n id: 'deduplicationKey',\n type: 'text',\n label: 'Deduplication Key',\n placeholder: 'Optional — prevents duplicate sends',\n formulaEnabled: true,\n },\n ],\n bpmnEntry: (id) => `Send Notification: ${id}`,\n bpmnExit: (id) => `End Notification: ${id}`,\n emitBpmnElements: (id, data) => {\n const d = data as Record<string, unknown>;\n return [{ id, $type: 'bpmn:SendTask', name: `Notify via ${d.channel ?? 'channel'}` }];\n },\n});\n","import React from 'react';\nimport { MdCallSplit } from 'react-icons/md';\nimport { defineNode } from '../defineNode';\n\nconst CONDITION_OPERATORS = [\n { label: 'equals (=)', value: 'eq' },\n { label: 'not equals (≠)', value: 'neq' },\n { label: 'greater than (>)', value: 'gt' },\n { label: 'greater or equal (≥)', value: 'gte' },\n { label: 'less than (<)', value: 'lt' },\n { label: 'less or equal (≤)', value: 'lte' },\n { label: 'contains', value: 'contains' },\n { label: 'starts with', value: 'startsWith' },\n { label: 'ends with', value: 'endsWith' },\n { label: 'is empty', value: 'isEmpty' },\n { label: 'is not empty', value: 'isNotEmpty' },\n];\n\nexport const conditionBranchDescriptor = defineNode({\n type: 'conditionBranch',\n label: 'Condition Branch',\n icon: React.createElement(MdCallSplit, { size: 18, color: '#512da8' }),\n matches: (id) => id.startsWith('conditionBranch-'),\n reactFlowType: 'conditionBranchNode',\n /** Initial branch labels — canvas uses these keys to initialise BranchMap on insert.\n * Pre-seeded as Workato-style IF / ELSE IF / ELSE chain. */\n branchLabels: { branch1: 'IF · Branch 1', branch2: 'ELSE IF · Branch 2', default: 'ELSE' },\n formSchema: [\n {\n id: 'title',\n type: 'text',\n label: 'Node Label',\n placeholder: 'e.g. Route by User Role',\n },\n {\n id: 'branchConfigs',\n type: 'array',\n label: 'Branches',\n required: true,\n children: [\n {\n id: 'kind',\n type: 'select',\n label: 'Branch Type',\n required: true,\n options: [\n { label: 'IF', value: 'if' },\n { label: 'ELSE IF', value: 'elseif' },\n { label: 'ELSE', value: 'else' },\n ],\n // Default for new branches is \"elseif\" so the chain reads correctly when\n // appended between the first IF and the trailing ELSE.\n placeholder: 'elseif',\n },\n {\n id: 'key',\n type: 'text',\n label: 'Branch Key',\n required: true,\n placeholder: 'e.g. admin (no spaces)',\n },\n {\n id: 'label',\n type: 'text',\n label: 'Branch Label',\n required: true,\n placeholder: 'e.g. Admin Users',\n },\n {\n id: 'conditions',\n type: 'array',\n label: 'Conditions',\n // ELSE branches have no condition by definition — hide the array.\n shouldHide: ({ values }: { values: Record<string, unknown> }) =>\n values.kind === 'else',\n children: [\n {\n id: 'field',\n type: 'text',\n label: 'Field / Variable',\n required: true,\n placeholder: 'e.g. user.role',\n formulaEnabled: true,\n },\n {\n id: 'operator',\n type: 'select',\n label: 'Operator',\n required: true,\n options: CONDITION_OPERATORS,\n },\n {\n id: 'value',\n type: 'text',\n label: 'Value',\n placeholder: 'e.g. admin',\n formulaEnabled: true,\n shouldHide: ({ values }: { values: Record<string, unknown> }) =>\n values.operator === 'isEmpty' || values.operator === 'isNotEmpty',\n },\n {\n id: 'logicalOperator',\n type: 'select',\n label: 'Combine with next',\n options: [\n { label: 'AND', value: 'AND' },\n { label: 'OR', value: 'OR' },\n ],\n },\n ],\n },\n ],\n },\n {\n id: 'defaultBranch',\n type: 'text',\n label: 'Default Branch Key (fallback if no condition matches)',\n placeholder: 'e.g. default',\n },\n ],\n bpmnEntry: (id) => `Condition Branch: ${id}`,\n bpmnExit: (id) => `End Condition Branch: ${id}`,\n emitBpmnElements: (id, data) => {\n const d = data as Record<string, unknown>;\n const branches = (d.branchConfigs as Array<{ key: string; label: string }> | undefined) ?? [];\n return [\n { id, $type: 'bpmn:ExclusiveGateway', name: (d.title as string) ?? 'Condition Branch' },\n ...branches.map((b) => ({\n id: `${id}-${b.key}`,\n $type: 'bpmn:SequenceFlow',\n name: b.label,\n })),\n ];\n },\n});\n","import React from 'react';\nimport { MdWebhook } from 'react-icons/md';\nimport { WorkflowTemplate } from '../../WorkflowCanvas/types';\nimport { NODE_DESCRIPTOR_ICON_SIZE } from '../../WorkflowCanvas/canvasTokens';\nimport { defineNode } from '../defineNode';\n\nexport const webhookTriggerDescriptor = defineNode({\n type: 'webhookTrigger',\n label: 'Webhook Trigger',\n icon: React.createElement(MdWebhook, { size: NODE_DESCRIPTOR_ICON_SIZE, color: '#1565c0' }),\n matches: (id) => id.startsWith('webhookTrigger-'),\n reactFlowType: 'webhookTriggerNode',\n formSchema: [\n {\n id: 'endpointUrl',\n type: 'text',\n label: 'Endpoint URL',\n disabled: true,\n placeholder: 'Generated after saving',\n },\n {\n id: 'authMethod',\n type: 'select',\n label: 'Authentication',\n required: true,\n options: [\n { label: 'None', value: 'none' },\n { label: 'API Key', value: 'api-key' },\n { label: 'HMAC Signature', value: 'hmac' },\n ],\n },\n {\n id: 'apiKeyHeader',\n type: 'text',\n label: 'API Key Header Name',\n placeholder: 'e.g. X-API-Key',\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.authMethod !== 'api-key',\n },\n {\n id: 'hmacSecret',\n type: 'text',\n label: 'HMAC Secret',\n placeholder: 'Shared secret for signature verification',\n shouldHide: ({ values }: { values: Record<string, unknown> }) => values.authMethod !== 'hmac',\n },\n {\n id: 'payloadDescription',\n type: 'textarea',\n label: 'Expected Payload Description',\n placeholder: 'Describe the expected JSON payload fields...',\n },\n ],\n bpmnEntry: (id) => `Webhook Trigger: ${id}`,\n bpmnExit: (id) => `End Webhook Trigger: ${id}`,\n emitBpmnElements: (id) => [{ id, $type: 'bpmn:StartEvent', name: 'Webhook Trigger' }],\n});\n\nexport const webhookTriggerTemplate: WorkflowTemplate = {\n triggerKey: 'WEBHOOK_TRIGGER',\n label: 'Incoming Webhook',\n description: 'Start this workflow when an HTTP POST is received at a generated endpoint.',\n triggerCategory: 'webhook',\n icon: React.createElement(MdWebhook, { size: NODE_DESCRIPTOR_ICON_SIZE, color: '#1565c0' }),\n};\n","import React from 'react';\nimport { MdAccountTree } from 'react-icons/md';\nimport { NodeDescriptor } from '../../WorkflowCanvas/types';\nimport { defineNode } from '../defineNode';\n\n/**\n * Sub-Workflow node — calls another saved workflow by ID.\n *\n * The host app must provide `fetchWorkflowOptions` at registration time so the\n * `workflowId` select field can populate. Inject it via the descriptor factory:\n *\n * import { makeSubWorkflowDescriptor } from '@miniorange/flowforge';\n * nodeTypeRegistry.register(makeSubWorkflowDescriptor({\n * fetchWorkflowOptions: async () => myApi.listWorkflows(),\n * }));\n */\nexport interface SubWorkflowDescriptorOptions {\n /** Return a list of available workflows for the workflowId select field */\n fetchWorkflowOptions?: () => Promise<Array<{ label: string; value: string }>>;\n}\n\nexport function makeSubWorkflowDescriptor(opts: SubWorkflowDescriptorOptions = {}): NodeDescriptor {\n return defineNode({\n type: 'subWorkflow',\n label: 'Sub-Workflow',\n icon: React.createElement(MdAccountTree, { size: 18, color: '#00695c' }),\n matches: (id) => id.startsWith('subWorkflow-'),\n reactFlowType: 'subWorkflowNode',\n formSchema: [\n {\n id: 'workflowId',\n type: 'select',\n label: 'Workflow to Call',\n required: true,\n placeholder: 'Select a workflow...',\n ...(opts.fetchWorkflowOptions\n ? { fetchOptions: opts.fetchWorkflowOptions }\n : { options: [] }),\n },\n {\n id: 'workflowLabel',\n type: 'text',\n label: 'Display Name (optional)',\n placeholder: 'Override display name shown on canvas',\n },\n {\n id: 'inputMapping',\n type: 'key-value',\n label: 'Input Mapping',\n placeholder: 'Map parent variables → sub-workflow inputs',\n formulaEnabled: true,\n },\n {\n id: 'outputMapping',\n type: 'key-value',\n label: 'Output Mapping',\n placeholder: 'Map sub-workflow outputs → parent variables',\n },\n {\n id: 'waitForCompletion',\n type: 'toggle',\n label: 'Wait for sub-workflow to complete before continuing',\n },\n {\n id: 'continueOnError',\n type: 'toggle',\n label: 'Continue parent workflow if sub-workflow fails',\n },\n ],\n bpmnEntry: (id) => `Sub-Workflow Call: ${id}`,\n bpmnExit: (id) => `End Sub-Workflow Call: ${id}`,\n emitBpmnElements: (id, data) => {\n const d = data as Record<string, unknown>;\n return [{\n id,\n $type: 'bpmn:CallActivity',\n name: (d.workflowLabel as string) || (d.workflowId as string) || 'Sub-Workflow',\n calledElement: d.workflowId as string,\n }];\n },\n });\n}\n\n/** Pre-built static descriptor (no dynamic workflow list). Swap for makeSubWorkflowDescriptor when you have an API. */\nexport const subWorkflowDescriptor: NodeDescriptor = makeSubWorkflowDescriptor();\n","import { NodeDescriptor } from '../WorkflowCanvas/types';\n\nexport class NodeTypeRegistry {\n private descriptors = new Map<string, NodeDescriptor>();\n\n register(descriptor: NodeDescriptor): this {\n this.descriptors.set(descriptor.type, descriptor);\n return this;\n }\n\n forType(type: string): NodeDescriptor | undefined {\n return this.descriptors.get(type);\n }\n\n forId(id: string): NodeDescriptor | undefined {\n for (const d of this.descriptors.values()) {\n if (d.matches(id)) return d;\n }\n return undefined;\n }\n\n list(): NodeDescriptor[] {\n return [...this.descriptors.values()];\n }\n}\n\nexport const nodeTypeRegistry = new NodeTypeRegistry();\nexport type { NodeDescriptor };\n\n// ── Base node + factory ────────────────────────────────────────────────────\nexport { defineNode, baseNodeDefaults } from './defineNode';\n\n// ── Built-in node descriptors ──────────────────────────────────────────────\nexport { startEventDescriptor } from './descriptors/startEventDescriptor';\nexport { endEventDescriptor } from './descriptors/endEventDescriptor';\nexport { restApiDescriptor } from './descriptors/restApiDescriptor';\nexport { notificationDescriptor } from './descriptors/notificationDescriptor';\nexport { conditionBranchDescriptor } from './descriptors/conditionBranchDescriptor';\nexport { webhookTriggerDescriptor, webhookTriggerTemplate } from './descriptors/webhookDescriptors';\nexport { subWorkflowDescriptor, makeSubWorkflowDescriptor } from './descriptors/subWorkflowDescriptor';\nexport type { SubWorkflowDescriptorOptions } from './descriptors/subWorkflowDescriptor';\n"],"names":["baseNodeDefaults","id","defineNode","overrides","startEventDescriptor","React","MdPlayCircleOutline","endEventDescriptor","MdStopCircle","restApiDescriptor","MdHttp","values","data","d","notificationDescriptor","MdNotifications","CONDITION_OPERATORS","conditionBranchDescriptor","MdCallSplit","branches","b","webhookTriggerDescriptor","MdWebhook","NODE_DESCRIPTOR_ICON_SIZE","webhookTriggerTemplate","makeSubWorkflowDescriptor","opts","MdAccountTree","subWorkflowDescriptor","NodeTypeRegistry","descriptor","type","nodeTypeRegistry"],"mappings":"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"}