@notmrabhi/flowforge 0.1.34 → 0.1.36

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 (38) hide show
  1. package/README.md +52 -0
  2. package/dist/{SchemaBuilderDrawer-BbkOK4Xc.js → SchemaBuilderDrawer-CUzYWGCN.js} +2 -2
  3. package/dist/{SchemaBuilderDrawer-BbkOK4Xc.js.map → SchemaBuilderDrawer-CUzYWGCN.js.map} +1 -1
  4. package/dist/{SchemaBuilderDrawer-BcaULxqB.js → SchemaBuilderDrawer-CiSdfXzJ.js} +2 -2
  5. package/dist/{SchemaBuilderDrawer-BcaULxqB.js.map → SchemaBuilderDrawer-CiSdfXzJ.js.map} +1 -1
  6. package/dist/canvas.cjs +1 -1
  7. package/dist/canvas.d.ts +101 -0
  8. package/dist/canvas.js +1 -1
  9. package/dist/core.d.ts +61 -0
  10. package/dist/form.cjs +1 -1
  11. package/dist/form.d.ts +12 -0
  12. package/dist/form.js +2 -2
  13. package/dist/{index-CEg1wTCw.js → index-B74jTc2b.js} +869 -862
  14. package/dist/{index-CEg1wTCw.js.map → index-B74jTc2b.js.map} +1 -1
  15. package/dist/{index-CYdDPwd2.js → index-B8-KKaH_.js} +2 -2
  16. package/dist/{index-CYdDPwd2.js.map → index-B8-KKaH_.js.map} +1 -1
  17. package/dist/{index-dhI8qsmP.js → index-Buv1ylwP.js} +2 -2
  18. package/dist/{index-dhI8qsmP.js.map → index-Buv1ylwP.js.map} +1 -1
  19. package/dist/{index-fcb3uyVA.js → index-CiU9_8f1.js} +2 -2
  20. package/dist/{index-fcb3uyVA.js.map → index-CiU9_8f1.js.map} +1 -1
  21. package/dist/{index-x1DrmceO.js → index-CqMPyOkL.js} +5 -5
  22. package/dist/{index-x1DrmceO.js.map → index-CqMPyOkL.js.map} +1 -1
  23. package/dist/{index-B9W10Fvn.js → index-DjKhaaWf.js} +2 -2
  24. package/dist/{index-B9W10Fvn.js.map → index-DjKhaaWf.js.map} +1 -1
  25. package/dist/index.cjs +1 -1
  26. package/dist/index.d.ts +61 -0
  27. package/dist/index.js +3 -3
  28. package/dist/nodeRegistry.d.ts +18 -0
  29. package/dist/templateRegistry.cjs +1 -1
  30. package/dist/templateRegistry.cjs.map +1 -1
  31. package/dist/templateRegistry.d.ts +49 -0
  32. package/dist/templateRegistry.js +63 -20
  33. package/dist/templateRegistry.js.map +1 -1
  34. package/dist/{templateSkeletons-CY4tkEp2.js → templateSkeletons-BTC2fk5u.js} +2 -2
  35. package/dist/{templateSkeletons-CY4tkEp2.js.map → templateSkeletons-BTC2fk5u.js.map} +1 -1
  36. package/dist/{templateSkeletons-BPIZ_EHv.js → templateSkeletons-DCvfog6-.js} +2 -2
  37. package/dist/{templateSkeletons-BPIZ_EHv.js.map → templateSkeletons-DCvfog6-.js.map} +1 -1
  38. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./index-x1DrmceO.js"),a=require("./SchemaBuilderDrawer-BcaULxqB.js");require("react/jsx-runtime");require("react");require("@mui/material");require("react-icons/md");const r=require("./nodeRegistry.cjs"),l=require("./templateRegistry.cjs"),i=require("./templateSkeletons-CY4tkEp2.js"),d=require("./messages-O9Tw_XXR.js"),n=require("./bpmn-CcuE2X_Q.js"),o=require("./GatewayBranchEdge-9YF32wwN.js");class u{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 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.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=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=i.FlowForgeCanvas;exports.SubWorkflowPreviewDrawer=i.SubWorkflowPreviewDrawer;exports.WorkflowCanvas=i.FlowForgeCanvas;exports.WorkflowExecutionHistory=i.WorkflowExecutionHistory;exports.WorkflowTemplateLibrary=i.WorkflowTemplateLibrary;exports.accessRequestSkeleton=i.accessRequestSkeleton;exports.offboardingSkeleton=i.offboardingSkeleton;exports.userOnboardingSkeleton=i.userOnboardingSkeleton;exports.webhookIntegrationSkeleton=i.webhookIntegrationSkeleton;exports.defaultFlowForgeMessages=d.defaultFlowForgeMessages;exports.loadWorkflowFromBpmn=n.loadWorkflowFromBpmn;exports.saveWorkflowToBpmn=n.saveWorkflowToBpmn;exports.ActionNode=o.ActionNode;exports.ApprovalNode=o.ApprovalNode;exports.EdgeWithPlusLabel=o.EdgeWithPlusLabel;exports.EndNode=o.EndNode;exports.FilterNode=o.FilterNode;exports.RestApiNode=o.RestApiNode;exports.StartNode=o.StartNode;exports.TriggerNode=o.TriggerNode;exports.WebhookTriggerNode=o.WebhookTriggerNode;exports.builtInNodeTypes=o.builtInNodeTypes;exports.notificationChannelRegistry=c;
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 r=require("./nodeRegistry.cjs"),l=require("./templateRegistry.cjs"),i=require("./templateSkeletons-BTC2fk5u.js"),d=require("./messages-O9Tw_XXR.js"),n=require("./bpmn-CcuE2X_Q.js"),o=require("./GatewayBranchEdge-9YF32wwN.js");class u{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 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.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=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=i.FlowForgeCanvas;exports.SubWorkflowPreviewDrawer=i.SubWorkflowPreviewDrawer;exports.WorkflowCanvas=i.FlowForgeCanvas;exports.WorkflowExecutionHistory=i.WorkflowExecutionHistory;exports.WorkflowTemplateLibrary=i.WorkflowTemplateLibrary;exports.accessRequestSkeleton=i.accessRequestSkeleton;exports.offboardingSkeleton=i.offboardingSkeleton;exports.userOnboardingSkeleton=i.userOnboardingSkeleton;exports.webhookIntegrationSkeleton=i.webhookIntegrationSkeleton;exports.defaultFlowForgeMessages=d.defaultFlowForgeMessages;exports.loadWorkflowFromBpmn=n.loadWorkflowFromBpmn;exports.saveWorkflowToBpmn=n.saveWorkflowToBpmn;exports.ActionNode=o.ActionNode;exports.ApprovalNode=o.ApprovalNode;exports.EdgeWithPlusLabel=o.EdgeWithPlusLabel;exports.EndNode=o.EndNode;exports.FilterNode=o.FilterNode;exports.RestApiNode=o.RestApiNode;exports.StartNode=o.StartNode;exports.TriggerNode=o.TriggerNode;exports.WebhookTriggerNode=o.WebhookTriggerNode;exports.builtInNodeTypes=o.builtInNodeTypes;exports.notificationChannelRegistry=c;
2
2
  //# sourceMappingURL=index.cjs.map
package/dist/index.d.ts CHANGED
@@ -41,6 +41,22 @@ export declare interface AddStepContext {
41
41
  branch?: string;
42
42
  }
43
43
 
44
+ /**
45
+ * Wire shape the backend `/api/v1/workflow-template` endpoint is expected
46
+ * to return. Top-level fields mirror the persistence model; everything
47
+ * UI-related lives under `templateUI`. Use with `templateRegistry.registerFromApi(list)`.
48
+ */
49
+ export declare interface ApiWorkflowTemplate {
50
+ key: string;
51
+ name: string;
52
+ state?: string;
53
+ description?: string;
54
+ allowedTasks?: string[];
55
+ allowedSources?: string[];
56
+ configuration?: Record<string, unknown>;
57
+ templateUI?: Partial<Omit<WorkflowTemplate, 'triggerKey' | 'label' | 'description' | 'availableTasks'>>;
58
+ }
59
+
44
60
  export declare const ApprovalNode: ({ id, data }: NodeProps) => JSX_2.Element;
45
61
 
46
62
  /** True if the AST contains at least one non-text node. */
@@ -500,6 +516,18 @@ export declare interface FieldDescriptor {
500
516
  shouldHide?: (ctx: FieldContext) => boolean;
501
517
  shouldDisable?: (ctx: FieldContext) => boolean;
502
518
  shouldRequire?: (ctx: FieldContext) => boolean;
519
+ /**
520
+ * When true, the field's value is auto-cleared (reset to `defaultValue`,
521
+ * or removed if no default) any time `shouldHide` evaluates to true —
522
+ * including on mount when the saved data has orphan values from a prior
523
+ * configuration. Default: false (values persist while hidden, preserving
524
+ * legacy behavior).
525
+ *
526
+ * Use this on conditional fields where stale data would corrupt the
527
+ * payload (e.g. `template` should be empty when `valueSource !== 'template'`).
528
+ */
529
+ clearOnHide?: boolean;
530
+ defaultValue?: unknown;
503
531
  compute?: (ctx: FieldContext) => unknown;
504
532
  transform?: FieldTransform;
505
533
  onChange?: (value: unknown, ctx: FieldContext & {
@@ -1278,13 +1306,40 @@ export declare interface TabsFieldDescriptor extends FieldDescriptor {
1278
1306
 
1279
1307
  export declare class TemplateRegistry {
1280
1308
  private templates;
1309
+ /**
1310
+ * Register a template. Normalises `allowedTasks` (the backend's name) →
1311
+ * `availableTasks` (FlowForge's canonical name) so consumers can pass
1312
+ * either without rewriting.
1313
+ */
1281
1314
  register(template: WorkflowTemplate): this;
1315
+ /**
1316
+ * Register a list of templates fetched from `GET /api/v1/workflow-template`.
1317
+ *
1318
+ * The API shape is:
1319
+ * {
1320
+ * key, name, description, allowedTasks, allowedSources,
1321
+ * configuration, // runtime BPMN — ignored by the canvas
1322
+ * templateUI: { // ← UI bag, spread onto the template
1323
+ * triggerCategory, icon, tags, category, author, popularity,
1324
+ * source, product, taskLabels, maxTasks, skeletonState, …
1325
+ * }
1326
+ * }
1327
+ *
1328
+ * Anything in `templateUI` overrides the top-level shorthand where there's
1329
+ * an overlap. Bad rows (missing `key`) are skipped with a DEV warning
1330
+ * rather than throwing, so one broken template doesn't blank the picker.
1331
+ *
1332
+ * Returns `this` for chaining and the count of templates registered.
1333
+ */
1334
+ registerFromApi(list: ApiWorkflowTemplate[]): this;
1282
1335
  lookup(triggerKey: string): WorkflowTemplate | undefined;
1283
1336
  list(): WorkflowTemplate[];
1284
1337
  listByCategory(category: string): WorkflowTemplate[];
1285
1338
  listByTag(tag: string): WorkflowTemplate[];
1286
1339
  search(query: string): WorkflowTemplate[];
1287
1340
  categories(): string[];
1341
+ /** Remove every template — useful before re-loading from backend. */
1342
+ clear(): this;
1288
1343
  }
1289
1344
 
1290
1345
  export declare const templateRegistry: TemplateRegistry;
@@ -1456,7 +1511,13 @@ export declare interface WorkflowTemplate {
1456
1511
  description?: string;
1457
1512
  icon?: ReactNode;
1458
1513
  triggerCategory?: 'event' | 'scheduler' | 'webhook' | string;
1514
+ /**
1515
+ * Task IDs (descriptor types) that can be inserted into this workflow.
1516
+ * `allowedTasks` is accepted as an alias for backend payloads that use
1517
+ * that name — TemplateRegistry.register() normalises them.
1518
+ */
1459
1519
  availableTasks?: string[];
1520
+ allowedTasks?: string[];
1460
1521
  maxTasks?: number;
1461
1522
  taskLabels?: Record<string, string>;
1462
1523
  fixedNodes?: FixedNode[];
package/dist/index.js CHANGED
@@ -1,12 +1,12 @@
1
- import { D as c, F as u, a as m, b as f, c as g, I as F, T as h, V as b, d as k, e as T, f as w, 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 O, x as q, y as H, z as M, A as _ } from "./index-CEg1wTCw.js";
2
- import { F as Y, S as G, a as J, u as K } from "./SchemaBuilderDrawer-BbkOK4Xc.js";
1
+ import { D as c, F as u, a as m, b as f, c as g, I as F, T as h, V as b, d as k, e as T, f as w, 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 O, x as q, y as H, 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";
3
3
  import "react/jsx-runtime";
4
4
  import "react";
5
5
  import "@mui/material";
6
6
  import "react-icons/md";
7
7
  import { NodeTypeRegistry as U, baseNodeDefaults as X, conditionBranchDescriptor as Z, defineNode as $, endEventDescriptor as ee, makeSubWorkflowDescriptor as ae, nodeTypeRegistry as se, notificationDescriptor as re, restApiDescriptor as oe, startEventDescriptor as te, subWorkflowDescriptor as ie, webhookTriggerDescriptor as le, webhookTriggerTemplate as ne } from "./nodeRegistry.js";
8
8
  import { TemplateRegistry as de, templateRegistry as ce } from "./templateRegistry.js";
9
- import { F as me, S as fe, F as ge, W as Fe, a as he, b as be, o as ke, u as Te, w as we } from "./templateSkeletons-BPIZ_EHv.js";
9
+ import { F as me, S as fe, F as ge, W as Fe, a as he, b as be, o as ke, u as Te, w as we } from "./templateSkeletons-DCvfog6-.js";
10
10
  import { d as ye } from "./messages-CO299wPN.js";
11
11
  import { l as De, s as Ne } from "./bpmn-CtfWDaOY.js";
12
12
  import { A as We, b as Ae, E as Pe, c as ve, F as Ee, R as Ce, S as Ie, T as Be, W as ze, e as Ve } from "./GatewayBranchEdge-Dxoy5B1A.js";
@@ -149,6 +149,18 @@ declare interface FieldDescriptor {
149
149
  shouldHide?: (ctx: FieldContext) => boolean;
150
150
  shouldDisable?: (ctx: FieldContext) => boolean;
151
151
  shouldRequire?: (ctx: FieldContext) => boolean;
152
+ /**
153
+ * When true, the field's value is auto-cleared (reset to `defaultValue`,
154
+ * or removed if no default) any time `shouldHide` evaluates to true —
155
+ * including on mount when the saved data has orphan values from a prior
156
+ * configuration. Default: false (values persist while hidden, preserving
157
+ * legacy behavior).
158
+ *
159
+ * Use this on conditional fields where stale data would corrupt the
160
+ * payload (e.g. `template` should be empty when `valueSource !== 'template'`).
161
+ */
162
+ clearOnHide?: boolean;
163
+ defaultValue?: unknown;
152
164
  compute?: (ctx: FieldContext) => unknown;
153
165
  transform?: FieldTransform;
154
166
  onChange?: (value: unknown, ctx: FieldContext & {
@@ -324,7 +336,13 @@ declare interface WorkflowTemplate {
324
336
  description?: string;
325
337
  icon?: ReactNode;
326
338
  triggerCategory?: 'event' | 'scheduler' | 'webhook' | string;
339
+ /**
340
+ * Task IDs (descriptor types) that can be inserted into this workflow.
341
+ * `allowedTasks` is accepted as an alias for backend payloads that use
342
+ * that name — TemplateRegistry.register() normalises them.
343
+ */
327
344
  availableTasks?: string[];
345
+ allowedTasks?: string[];
328
346
  maxTasks?: number;
329
347
  taskLabels?: Record<string, string>;
330
348
  fixedNodes?: FixedNode[];
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class o{constructor(){this.templates=new Map}register(e){return this.templates.set(e.triggerKey,e),this}lookup(e){return this.templates.get(e)}list(){return[...this.templates.values()]}listByCategory(e){return this.list().filter(t=>t.category===e)}listByTag(e){return this.list().filter(t=>{var s;return(s=t.tags)==null?void 0:s.includes(e)})}search(e){const t=e.toLowerCase();return this.list().filter(s=>{var r,i,a;return s.label.toLowerCase().includes(t)||((r=s.description)==null?void 0:r.toLowerCase().includes(t))||((i=s.tags)==null?void 0:i.some(l=>l.toLowerCase().includes(t)))||((a=s.category)==null?void 0:a.toLowerCase().includes(t))})}categories(){const e=new Set;return this.list().forEach(t=>{t.category&&e.add(t.category)}),Array.from(e)}}const c=new o;exports.TemplateRegistry=o;exports.templateRegistry=c;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class l{constructor(){this.templates=new Map}register(t){const e={...t,availableTasks:t.availableTasks??t.allowedTasks};return this.templates.set(e.triggerKey,e),this}registerFromApi(t){for(const e of t??[])e!=null&&e.key&&this.register({triggerKey:e.key,label:e.name??e.key,description:e.description,availableTasks:e.allowedTasks,...e.templateUI??{}});return this}lookup(t){return this.templates.get(t)}list(){return[...this.templates.values()]}listByCategory(t){return this.list().filter(e=>e.category===t)}listByTag(t){return this.list().filter(e=>{var s;return(s=e.tags)==null?void 0:s.includes(t)})}search(t){const e=t.toLowerCase();return this.list().filter(s=>{var r,i,a;return s.label.toLowerCase().includes(e)||((r=s.description)==null?void 0:r.toLowerCase().includes(e))||((i=s.tags)==null?void 0:i.some(o=>o.toLowerCase().includes(e)))||((a=s.category)==null?void 0:a.toLowerCase().includes(e))})}categories(){const t=new Set;return this.list().forEach(e=>{e.category&&t.add(e.category)}),Array.from(t)}clear(){return this.templates.clear(),this}}const n=new l;exports.TemplateRegistry=l;exports.templateRegistry=n;
2
2
  //# sourceMappingURL=templateRegistry.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"templateRegistry.cjs","sources":["../src/templateRegistry/index.ts"],"sourcesContent":["import { WorkflowTemplate } from '../WorkflowCanvas/types';\r\n\r\nexport class TemplateRegistry {\r\n private templates = new Map<string, WorkflowTemplate>();\r\n\r\n register(template: WorkflowTemplate): this {\r\n this.templates.set(template.triggerKey, template);\r\n return this;\r\n }\r\n\r\n lookup(triggerKey: string): WorkflowTemplate | undefined {\r\n return this.templates.get(triggerKey);\r\n }\r\n\r\n list(): WorkflowTemplate[] {\r\n return [...this.templates.values()];\r\n }\r\n\r\n listByCategory(category: string): WorkflowTemplate[] {\r\n return this.list().filter((t) => t.category === category);\r\n }\r\n\r\n listByTag(tag: string): WorkflowTemplate[] {\r\n return this.list().filter((t) => t.tags?.includes(tag));\r\n }\r\n\r\n search(query: string): WorkflowTemplate[] {\r\n const q = query.toLowerCase();\r\n return this.list().filter(\r\n (t) =>\r\n t.label.toLowerCase().includes(q) ||\r\n t.description?.toLowerCase().includes(q) ||\r\n t.tags?.some((tag) => tag.toLowerCase().includes(q)) ||\r\n t.category?.toLowerCase().includes(q),\r\n );\r\n }\r\n\r\n categories(): string[] {\r\n const cats = new Set<string>();\r\n this.list().forEach((t) => { if (t.category) cats.add(t.category); });\r\n return Array.from(cats);\r\n }\r\n}\r\n\r\nexport const templateRegistry = new TemplateRegistry();\r\nexport type { WorkflowTemplate };\r\n"],"names":["TemplateRegistry","template","triggerKey","category","tag","_a","query","q","t","_b","_c","cats","templateRegistry"],"mappings":"gFAEO,MAAMA,CAAiB,CAAvB,aAAA,CACL,KAAQ,cAAgB,GAA8B,CAEtD,SAASC,EAAkC,CACzC,YAAK,UAAU,IAAIA,EAAS,WAAYA,CAAQ,EACzC,IACT,CAEA,OAAOC,EAAkD,CACvD,OAAO,KAAK,UAAU,IAAIA,CAAU,CACtC,CAEA,MAA2B,CACzB,MAAO,CAAC,GAAG,KAAK,UAAU,QAAQ,CACpC,CAEA,eAAeC,EAAsC,CACnD,OAAO,KAAK,OAAO,OAAQ,GAAM,EAAE,WAAaA,CAAQ,CAC1D,CAEA,UAAUC,EAAiC,CACzC,OAAO,KAAK,KAAA,EAAO,OAAQ,UAAM,OAAAC,EAAA,EAAE,OAAF,YAAAA,EAAQ,SAASD,GAAI,CACxD,CAEA,OAAOE,EAAmC,CACxC,MAAMC,EAAID,EAAM,YAAA,EAChB,OAAO,KAAK,OAAO,OAChBE,GAAA,WACC,OAAAA,EAAE,MAAM,cAAc,SAASD,CAAC,KAChCF,EAAAG,EAAE,cAAF,YAAAH,EAAe,cAAc,SAASE,OACtCE,EAAAD,EAAE,OAAF,YAAAC,EAAQ,KAAML,GAAQA,EAAI,cAAc,SAASG,CAAC,OAClDG,EAAAF,EAAE,WAAF,YAAAE,EAAY,cAAc,SAASH,IAAC,CAE1C,CAEA,YAAuB,CACrB,MAAMI,MAAW,IACjB,YAAK,KAAA,EAAO,QAAS,GAAM,CAAM,EAAE,UAAUA,EAAK,IAAI,EAAE,QAAQ,CAAG,CAAC,EAC7D,MAAM,KAAKA,CAAI,CACxB,CACF,CAEO,MAAMC,EAAmB,IAAIZ"}
1
+ {"version":3,"file":"templateRegistry.cjs","sources":["../src/templateRegistry/index.ts"],"sourcesContent":["import type { WorkflowTemplate, ApiWorkflowTemplate } from '../WorkflowCanvas/types';\n\nexport class TemplateRegistry {\n private templates = new Map<string, WorkflowTemplate>();\n\n /**\n * Register a template. Normalises `allowedTasks` (the backend's name) →\n * `availableTasks` (FlowForge's canonical name) so consumers can pass\n * either without rewriting.\n */\n register(template: WorkflowTemplate): this {\n const normalised: WorkflowTemplate = {\n ...template,\n availableTasks: template.availableTasks ?? template.allowedTasks,\n };\n this.templates.set(normalised.triggerKey, normalised);\n return this;\n }\n\n /**\n * Register a list of templates fetched from `GET /api/v1/workflow-template`.\n *\n * The API shape is:\n * {\n * key, name, description, allowedTasks, allowedSources,\n * configuration, // runtime BPMN — ignored by the canvas\n * templateUI: { // ← UI bag, spread onto the template\n * triggerCategory, icon, tags, category, author, popularity,\n * source, product, taskLabels, maxTasks, skeletonState, …\n * }\n * }\n *\n * Anything in `templateUI` overrides the top-level shorthand where there's\n * an overlap. Bad rows (missing `key`) are skipped with a DEV warning\n * rather than throwing, so one broken template doesn't blank the picker.\n *\n * Returns `this` for chaining and the count of templates registered.\n */\n registerFromApi(list: ApiWorkflowTemplate[]): this {\n for (const t of list ?? []) {\n if (!t?.key) {\n if (import.meta.env?.DEV) {\n // eslint-disable-next-line no-console\n console.warn('[FlowForge] templateRegistry.registerFromApi: skipped row without `key`', t);\n }\n continue;\n }\n this.register({\n triggerKey: t.key,\n label: t.name ?? t.key,\n description: t.description,\n availableTasks: t.allowedTasks,\n ...(t.templateUI ?? {}),\n } as WorkflowTemplate);\n }\n return this;\n }\n\n lookup(triggerKey: string): WorkflowTemplate | undefined {\n return this.templates.get(triggerKey);\n }\n\n list(): WorkflowTemplate[] {\n return [...this.templates.values()];\n }\n\n listByCategory(category: string): WorkflowTemplate[] {\n return this.list().filter((t) => t.category === category);\n }\n\n listByTag(tag: string): WorkflowTemplate[] {\n return this.list().filter((t) => t.tags?.includes(tag));\n }\n\n search(query: string): WorkflowTemplate[] {\n const q = query.toLowerCase();\n return this.list().filter(\n (t) =>\n t.label.toLowerCase().includes(q) ||\n t.description?.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q)) ||\n t.category?.toLowerCase().includes(q),\n );\n }\n\n categories(): string[] {\n const cats = new Set<string>();\n this.list().forEach((t) => { if (t.category) cats.add(t.category); });\n return Array.from(cats);\n }\n\n /** Remove every template — useful before re-loading from backend. */\n clear(): this {\n this.templates.clear();\n return this;\n }\n}\n\nexport const templateRegistry = new TemplateRegistry();\nexport type { WorkflowTemplate, ApiWorkflowTemplate };\n"],"names":["TemplateRegistry","template","normalised","list","t","triggerKey","category","tag","_a","query","q","_b","_c","cats","templateRegistry"],"mappings":"gFAEO,MAAMA,CAAiB,CAAvB,aAAA,CACL,KAAQ,cAAgB,GAA8B,CAOtD,SAASC,EAAkC,CACzC,MAAMC,EAA+B,CACnC,GAAGD,EACH,eAAgBA,EAAS,gBAAkBA,EAAS,YAAA,EAEtD,YAAK,UAAU,IAAIC,EAAW,WAAYA,CAAU,EAC7C,IACT,CAqBA,gBAAgBC,EAAmC,CACjD,UAAWC,KAAKD,GAAQ,GACjBC,GAAA,MAAAA,EAAG,KAOR,KAAK,SAAS,CACZ,WAAYA,EAAE,IACd,MAAOA,EAAE,MAAQA,EAAE,IACnB,YAAaA,EAAE,YACf,eAAgBA,EAAE,aAClB,GAAIA,EAAE,YAAc,CAAA,CAAC,CACF,EAEvB,OAAO,IACT,CAEA,OAAOC,EAAkD,CACvD,OAAO,KAAK,UAAU,IAAIA,CAAU,CACtC,CAEA,MAA2B,CACzB,MAAO,CAAC,GAAG,KAAK,UAAU,QAAQ,CACpC,CAEA,eAAeC,EAAsC,CACnD,OAAO,KAAK,OAAO,OAAQF,GAAMA,EAAE,WAAaE,CAAQ,CAC1D,CAEA,UAAUC,EAAiC,CACzC,OAAO,KAAK,KAAA,EAAO,OAAQH,UAAM,OAAAI,EAAAJ,EAAE,OAAF,YAAAI,EAAQ,SAASD,GAAI,CACxD,CAEA,OAAOE,EAAmC,CACxC,MAAMC,EAAID,EAAM,YAAA,EAChB,OAAO,KAAK,OAAO,OAChBL,GAAA,WACC,OAAAA,EAAE,MAAM,cAAc,SAASM,CAAC,KAChCF,EAAAJ,EAAE,cAAF,YAAAI,EAAe,cAAc,SAASE,OACtCC,EAAAP,EAAE,OAAF,YAAAO,EAAQ,KAAMJ,GAAQA,EAAI,cAAc,SAASG,CAAC,OAClDE,EAAAR,EAAE,WAAF,YAAAQ,EAAY,cAAc,SAASF,IAAC,CAE1C,CAEA,YAAuB,CACrB,MAAMG,MAAW,IACjB,YAAK,KAAA,EAAO,QAAST,GAAM,CAAMA,EAAE,UAAUS,EAAK,IAAIT,EAAE,QAAQ,CAAG,CAAC,EAC7D,MAAM,KAAKS,CAAI,CACxB,CAGA,OAAc,CACZ,YAAK,UAAU,MAAA,EACR,IACT,CACF,CAEO,MAAMC,EAAmB,IAAId"}
@@ -1,5 +1,21 @@
1
1
  import { ReactNode } from 'react';
2
2
 
3
+ /**
4
+ * Wire shape the backend `/api/v1/workflow-template` endpoint is expected
5
+ * to return. Top-level fields mirror the persistence model; everything
6
+ * UI-related lives under `templateUI`. Use with `templateRegistry.registerFromApi(list)`.
7
+ */
8
+ export declare interface ApiWorkflowTemplate {
9
+ key: string;
10
+ name: string;
11
+ state?: string;
12
+ description?: string;
13
+ allowedTasks?: string[];
14
+ allowedSources?: string[];
15
+ configuration?: Record<string, unknown>;
16
+ templateUI?: Partial<Omit<WorkflowTemplate, 'triggerKey' | 'label' | 'description' | 'availableTasks'>>;
17
+ }
18
+
3
19
  declare type BranchChain = CanvasSlot[];
4
20
 
5
21
  declare interface BranchMap {
@@ -38,13 +54,40 @@ declare type SlotKind = 'start' | 'end' | 'addTrigger' | 'triggerFixed' | 'userT
38
54
 
39
55
  export declare class TemplateRegistry {
40
56
  private templates;
57
+ /**
58
+ * Register a template. Normalises `allowedTasks` (the backend's name) →
59
+ * `availableTasks` (FlowForge's canonical name) so consumers can pass
60
+ * either without rewriting.
61
+ */
41
62
  register(template: WorkflowTemplate): this;
63
+ /**
64
+ * Register a list of templates fetched from `GET /api/v1/workflow-template`.
65
+ *
66
+ * The API shape is:
67
+ * {
68
+ * key, name, description, allowedTasks, allowedSources,
69
+ * configuration, // runtime BPMN — ignored by the canvas
70
+ * templateUI: { // ← UI bag, spread onto the template
71
+ * triggerCategory, icon, tags, category, author, popularity,
72
+ * source, product, taskLabels, maxTasks, skeletonState, …
73
+ * }
74
+ * }
75
+ *
76
+ * Anything in `templateUI` overrides the top-level shorthand where there's
77
+ * an overlap. Bad rows (missing `key`) are skipped with a DEV warning
78
+ * rather than throwing, so one broken template doesn't blank the picker.
79
+ *
80
+ * Returns `this` for chaining and the count of templates registered.
81
+ */
82
+ registerFromApi(list: ApiWorkflowTemplate[]): this;
42
83
  lookup(triggerKey: string): WorkflowTemplate | undefined;
43
84
  list(): WorkflowTemplate[];
44
85
  listByCategory(category: string): WorkflowTemplate[];
45
86
  listByTag(tag: string): WorkflowTemplate[];
46
87
  search(query: string): WorkflowTemplate[];
47
88
  categories(): string[];
89
+ /** Remove every template — useful before re-loading from backend. */
90
+ clear(): this;
48
91
  }
49
92
 
50
93
  export declare const templateRegistry: TemplateRegistry;
@@ -60,7 +103,13 @@ export declare interface WorkflowTemplate {
60
103
  description?: string;
61
104
  icon?: ReactNode;
62
105
  triggerCategory?: 'event' | 'scheduler' | 'webhook' | string;
106
+ /**
107
+ * Task IDs (descriptor types) that can be inserted into this workflow.
108
+ * `allowedTasks` is accepted as an alias for backend payloads that use
109
+ * that name — TemplateRegistry.register() normalises them.
110
+ */
63
111
  availableTasks?: string[];
112
+ allowedTasks?: string[];
64
113
  maxTasks?: number;
65
114
  taskLabels?: Record<string, string>;
66
115
  fixedNodes?: FixedNode[];
@@ -1,44 +1,87 @@
1
- class l {
1
+ class o {
2
2
  constructor() {
3
3
  this.templates = /* @__PURE__ */ new Map();
4
4
  }
5
- register(e) {
5
+ /**
6
+ * Register a template. Normalises `allowedTasks` (the backend's name) →
7
+ * `availableTasks` (FlowForge's canonical name) so consumers can pass
8
+ * either without rewriting.
9
+ */
10
+ register(t) {
11
+ const e = {
12
+ ...t,
13
+ availableTasks: t.availableTasks ?? t.allowedTasks
14
+ };
6
15
  return this.templates.set(e.triggerKey, e), this;
7
16
  }
8
- lookup(e) {
9
- return this.templates.get(e);
17
+ /**
18
+ * Register a list of templates fetched from `GET /api/v1/workflow-template`.
19
+ *
20
+ * The API shape is:
21
+ * {
22
+ * key, name, description, allowedTasks, allowedSources,
23
+ * configuration, // runtime BPMN — ignored by the canvas
24
+ * templateUI: { // ← UI bag, spread onto the template
25
+ * triggerCategory, icon, tags, category, author, popularity,
26
+ * source, product, taskLabels, maxTasks, skeletonState, …
27
+ * }
28
+ * }
29
+ *
30
+ * Anything in `templateUI` overrides the top-level shorthand where there's
31
+ * an overlap. Bad rows (missing `key`) are skipped with a DEV warning
32
+ * rather than throwing, so one broken template doesn't blank the picker.
33
+ *
34
+ * Returns `this` for chaining and the count of templates registered.
35
+ */
36
+ registerFromApi(t) {
37
+ for (const e of t ?? [])
38
+ e != null && e.key && this.register({
39
+ triggerKey: e.key,
40
+ label: e.name ?? e.key,
41
+ description: e.description,
42
+ availableTasks: e.allowedTasks,
43
+ ...e.templateUI ?? {}
44
+ });
45
+ return this;
46
+ }
47
+ lookup(t) {
48
+ return this.templates.get(t);
10
49
  }
11
50
  list() {
12
51
  return [...this.templates.values()];
13
52
  }
14
- listByCategory(e) {
15
- return this.list().filter((t) => t.category === e);
53
+ listByCategory(t) {
54
+ return this.list().filter((e) => e.category === t);
16
55
  }
17
- listByTag(e) {
18
- return this.list().filter((t) => {
56
+ listByTag(t) {
57
+ return this.list().filter((e) => {
19
58
  var s;
20
- return (s = t.tags) == null ? void 0 : s.includes(e);
59
+ return (s = e.tags) == null ? void 0 : s.includes(t);
21
60
  });
22
61
  }
23
- search(e) {
24
- const t = e.toLowerCase();
62
+ search(t) {
63
+ const e = t.toLowerCase();
25
64
  return this.list().filter(
26
65
  (s) => {
27
- var r, i, a;
28
- return s.label.toLowerCase().includes(t) || ((r = s.description) == null ? void 0 : r.toLowerCase().includes(t)) || ((i = s.tags) == null ? void 0 : i.some((o) => o.toLowerCase().includes(t))) || ((a = s.category) == null ? void 0 : a.toLowerCase().includes(t));
66
+ var r, a, i;
67
+ return s.label.toLowerCase().includes(e) || ((r = s.description) == null ? void 0 : r.toLowerCase().includes(e)) || ((a = s.tags) == null ? void 0 : a.some((l) => l.toLowerCase().includes(e))) || ((i = s.category) == null ? void 0 : i.toLowerCase().includes(e));
29
68
  }
30
69
  );
31
70
  }
32
71
  categories() {
33
- const e = /* @__PURE__ */ new Set();
34
- return this.list().forEach((t) => {
35
- t.category && e.add(t.category);
36
- }), Array.from(e);
72
+ const t = /* @__PURE__ */ new Set();
73
+ return this.list().forEach((e) => {
74
+ e.category && t.add(e.category);
75
+ }), Array.from(t);
76
+ }
77
+ /** Remove every template — useful before re-loading from backend. */
78
+ clear() {
79
+ return this.templates.clear(), this;
37
80
  }
38
81
  }
39
- const n = new l();
82
+ const c = new o();
40
83
  export {
41
- l as TemplateRegistry,
42
- n as templateRegistry
84
+ o as TemplateRegistry,
85
+ c as templateRegistry
43
86
  };
44
87
  //# sourceMappingURL=templateRegistry.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"templateRegistry.js","sources":["../src/templateRegistry/index.ts"],"sourcesContent":["import { WorkflowTemplate } from '../WorkflowCanvas/types';\r\n\r\nexport class TemplateRegistry {\r\n private templates = new Map<string, WorkflowTemplate>();\r\n\r\n register(template: WorkflowTemplate): this {\r\n this.templates.set(template.triggerKey, template);\r\n return this;\r\n }\r\n\r\n lookup(triggerKey: string): WorkflowTemplate | undefined {\r\n return this.templates.get(triggerKey);\r\n }\r\n\r\n list(): WorkflowTemplate[] {\r\n return [...this.templates.values()];\r\n }\r\n\r\n listByCategory(category: string): WorkflowTemplate[] {\r\n return this.list().filter((t) => t.category === category);\r\n }\r\n\r\n listByTag(tag: string): WorkflowTemplate[] {\r\n return this.list().filter((t) => t.tags?.includes(tag));\r\n }\r\n\r\n search(query: string): WorkflowTemplate[] {\r\n const q = query.toLowerCase();\r\n return this.list().filter(\r\n (t) =>\r\n t.label.toLowerCase().includes(q) ||\r\n t.description?.toLowerCase().includes(q) ||\r\n t.tags?.some((tag) => tag.toLowerCase().includes(q)) ||\r\n t.category?.toLowerCase().includes(q),\r\n );\r\n }\r\n\r\n categories(): string[] {\r\n const cats = new Set<string>();\r\n this.list().forEach((t) => { if (t.category) cats.add(t.category); });\r\n return Array.from(cats);\r\n }\r\n}\r\n\r\nexport const templateRegistry = new TemplateRegistry();\r\nexport type { WorkflowTemplate };\r\n"],"names":["TemplateRegistry","template","triggerKey","category","tag","_a","query","q","t","_b","_c","cats","templateRegistry"],"mappings":"AAEO,MAAMA,EAAiB;AAAA,EAAvB,cAAA;AACL,SAAQ,gCAAgB,IAAA;AAAA,EAA8B;AAAA,EAEtD,SAASC,GAAkC;AACzC,gBAAK,UAAU,IAAIA,EAAS,YAAYA,CAAQ,GACzC;AAAA,EACT;AAAA,EAEA,OAAOC,GAAkD;AACvD,WAAO,KAAK,UAAU,IAAIA,CAAU;AAAA,EACtC;AAAA,EAEA,OAA2B;AACzB,WAAO,CAAC,GAAG,KAAK,UAAU,QAAQ;AAAA,EACpC;AAAA,EAEA,eAAeC,GAAsC;AACnD,WAAO,KAAK,OAAO,OAAO,CAAC,MAAM,EAAE,aAAaA,CAAQ;AAAA,EAC1D;AAAA,EAEA,UAAUC,GAAiC;AACzC,WAAO,KAAK,KAAA,EAAO,OAAO,CAAC;AArBxB,UAAAC;AAqB8B,cAAAA,IAAA,EAAE,SAAF,gBAAAA,EAAQ,SAASD;AAAA,KAAI;AAAA,EACxD;AAAA,EAEA,OAAOE,GAAmC;AACxC,UAAMC,IAAID,EAAM,YAAA;AAChB,WAAO,KAAK,OAAO;AAAA,MACjB,CAACE,MAAA;AA3BA,YAAAH,GAAAI,GAAAC;AA4BC,eAAAF,EAAE,MAAM,cAAc,SAASD,CAAC,OAChCF,IAAAG,EAAE,gBAAF,gBAAAH,EAAe,cAAc,SAASE,SACtCE,IAAAD,EAAE,SAAF,gBAAAC,EAAQ,KAAK,CAACL,MAAQA,EAAI,cAAc,SAASG,CAAC,SAClDG,IAAAF,EAAE,aAAF,gBAAAE,EAAY,cAAc,SAASH;AAAA;AAAA,IAAC;AAAA,EAE1C;AAAA,EAEA,aAAuB;AACrB,UAAMI,wBAAW,IAAA;AACjB,gBAAK,KAAA,EAAO,QAAQ,CAAC,MAAM;AAAE,MAAI,EAAE,YAAUA,EAAK,IAAI,EAAE,QAAQ;AAAA,IAAG,CAAC,GAC7D,MAAM,KAAKA,CAAI;AAAA,EACxB;AACF;AAEO,MAAMC,IAAmB,IAAIZ,EAAA;"}
1
+ {"version":3,"file":"templateRegistry.js","sources":["../src/templateRegistry/index.ts"],"sourcesContent":["import type { WorkflowTemplate, ApiWorkflowTemplate } from '../WorkflowCanvas/types';\n\nexport class TemplateRegistry {\n private templates = new Map<string, WorkflowTemplate>();\n\n /**\n * Register a template. Normalises `allowedTasks` (the backend's name) →\n * `availableTasks` (FlowForge's canonical name) so consumers can pass\n * either without rewriting.\n */\n register(template: WorkflowTemplate): this {\n const normalised: WorkflowTemplate = {\n ...template,\n availableTasks: template.availableTasks ?? template.allowedTasks,\n };\n this.templates.set(normalised.triggerKey, normalised);\n return this;\n }\n\n /**\n * Register a list of templates fetched from `GET /api/v1/workflow-template`.\n *\n * The API shape is:\n * {\n * key, name, description, allowedTasks, allowedSources,\n * configuration, // runtime BPMN — ignored by the canvas\n * templateUI: { // ← UI bag, spread onto the template\n * triggerCategory, icon, tags, category, author, popularity,\n * source, product, taskLabels, maxTasks, skeletonState, …\n * }\n * }\n *\n * Anything in `templateUI` overrides the top-level shorthand where there's\n * an overlap. Bad rows (missing `key`) are skipped with a DEV warning\n * rather than throwing, so one broken template doesn't blank the picker.\n *\n * Returns `this` for chaining and the count of templates registered.\n */\n registerFromApi(list: ApiWorkflowTemplate[]): this {\n for (const t of list ?? []) {\n if (!t?.key) {\n if (import.meta.env?.DEV) {\n // eslint-disable-next-line no-console\n console.warn('[FlowForge] templateRegistry.registerFromApi: skipped row without `key`', t);\n }\n continue;\n }\n this.register({\n triggerKey: t.key,\n label: t.name ?? t.key,\n description: t.description,\n availableTasks: t.allowedTasks,\n ...(t.templateUI ?? {}),\n } as WorkflowTemplate);\n }\n return this;\n }\n\n lookup(triggerKey: string): WorkflowTemplate | undefined {\n return this.templates.get(triggerKey);\n }\n\n list(): WorkflowTemplate[] {\n return [...this.templates.values()];\n }\n\n listByCategory(category: string): WorkflowTemplate[] {\n return this.list().filter((t) => t.category === category);\n }\n\n listByTag(tag: string): WorkflowTemplate[] {\n return this.list().filter((t) => t.tags?.includes(tag));\n }\n\n search(query: string): WorkflowTemplate[] {\n const q = query.toLowerCase();\n return this.list().filter(\n (t) =>\n t.label.toLowerCase().includes(q) ||\n t.description?.toLowerCase().includes(q) ||\n t.tags?.some((tag) => tag.toLowerCase().includes(q)) ||\n t.category?.toLowerCase().includes(q),\n );\n }\n\n categories(): string[] {\n const cats = new Set<string>();\n this.list().forEach((t) => { if (t.category) cats.add(t.category); });\n return Array.from(cats);\n }\n\n /** Remove every template — useful before re-loading from backend. */\n clear(): this {\n this.templates.clear();\n return this;\n }\n}\n\nexport const templateRegistry = new TemplateRegistry();\nexport type { WorkflowTemplate, ApiWorkflowTemplate };\n"],"names":["TemplateRegistry","template","normalised","list","t","triggerKey","category","tag","_a","query","q","_b","_c","cats","templateRegistry"],"mappings":"AAEO,MAAMA,EAAiB;AAAA,EAAvB,cAAA;AACL,SAAQ,gCAAgB,IAAA;AAAA,EAA8B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtD,SAASC,GAAkC;AACzC,UAAMC,IAA+B;AAAA,MACnC,GAAGD;AAAA,MACH,gBAAgBA,EAAS,kBAAkBA,EAAS;AAAA,IAAA;AAEtD,gBAAK,UAAU,IAAIC,EAAW,YAAYA,CAAU,GAC7C;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,gBAAgBC,GAAmC;AACjD,eAAWC,KAAKD,KAAQ;AACtB,MAAKC,KAAA,QAAAA,EAAG,OAOR,KAAK,SAAS;AAAA,QACZ,YAAYA,EAAE;AAAA,QACd,OAAOA,EAAE,QAAQA,EAAE;AAAA,QACnB,aAAaA,EAAE;AAAA,QACf,gBAAgBA,EAAE;AAAA,QAClB,GAAIA,EAAE,cAAc,CAAA;AAAA,MAAC,CACF;AAEvB,WAAO;AAAA,EACT;AAAA,EAEA,OAAOC,GAAkD;AACvD,WAAO,KAAK,UAAU,IAAIA,CAAU;AAAA,EACtC;AAAA,EAEA,OAA2B;AACzB,WAAO,CAAC,GAAG,KAAK,UAAU,QAAQ;AAAA,EACpC;AAAA,EAEA,eAAeC,GAAsC;AACnD,WAAO,KAAK,OAAO,OAAO,CAACF,MAAMA,EAAE,aAAaE,CAAQ;AAAA,EAC1D;AAAA,EAEA,UAAUC,GAAiC;AACzC,WAAO,KAAK,KAAA,EAAO,OAAO,CAACH;AArExB,UAAAI;AAqE8B,cAAAA,IAAAJ,EAAE,SAAF,gBAAAI,EAAQ,SAASD;AAAA,KAAI;AAAA,EACxD;AAAA,EAEA,OAAOE,GAAmC;AACxC,UAAMC,IAAID,EAAM,YAAA;AAChB,WAAO,KAAK,OAAO;AAAA,MACjB,CAACL,MAAA;AA3EA,YAAAI,GAAAG,GAAAC;AA4EC,eAAAR,EAAE,MAAM,cAAc,SAASM,CAAC,OAChCF,IAAAJ,EAAE,gBAAF,gBAAAI,EAAe,cAAc,SAASE,SACtCC,IAAAP,EAAE,SAAF,gBAAAO,EAAQ,KAAK,CAACJ,MAAQA,EAAI,cAAc,SAASG,CAAC,SAClDE,IAAAR,EAAE,aAAF,gBAAAQ,EAAY,cAAc,SAASF;AAAA;AAAA,IAAC;AAAA,EAE1C;AAAA,EAEA,aAAuB;AACrB,UAAMG,wBAAW,IAAA;AACjB,gBAAK,KAAA,EAAO,QAAQ,CAACT,MAAM;AAAE,MAAIA,EAAE,YAAUS,EAAK,IAAIT,EAAE,QAAQ;AAAA,IAAG,CAAC,GAC7D,MAAM,KAAKS,CAAI;AAAA,EACxB;AAAA;AAAA,EAGA,QAAc;AACZ,gBAAK,UAAU,MAAA,GACR;AAAA,EACT;AACF;AAEO,MAAMC,IAAmB,IAAId,EAAA;"}