@revenexx/studio-integrations 0.1.0

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 (106) hide show
  1. package/README.md +51 -0
  2. package/dist/module.d.mts +6 -0
  3. package/dist/module.json +9 -0
  4. package/dist/module.mjs +45 -0
  5. package/dist/runtime/components/Integrations/Layout.d.vue.ts +12 -0
  6. package/dist/runtime/components/Integrations/Layout.vue +20 -0
  7. package/dist/runtime/components/Integrations/Layout.vue.d.ts +12 -0
  8. package/dist/runtime/components/Integrations/NodeInspector.d.vue.ts +16 -0
  9. package/dist/runtime/components/Integrations/NodeInspector.vue +450 -0
  10. package/dist/runtime/components/Integrations/NodeInspector.vue.d.ts +16 -0
  11. package/dist/runtime/components/Integrations/NodePalette.d.vue.ts +2 -0
  12. package/dist/runtime/components/Integrations/NodePalette.vue +140 -0
  13. package/dist/runtime/components/Integrations/NodePalette.vue.d.ts +2 -0
  14. package/dist/runtime/components/Integrations/RunDetailDialog.d.vue.ts +11 -0
  15. package/dist/runtime/components/Integrations/RunDetailDialog.vue +169 -0
  16. package/dist/runtime/components/Integrations/RunDetailDialog.vue.d.ts +11 -0
  17. package/dist/runtime/components/Integrations/Sidebar.d.vue.ts +2 -0
  18. package/dist/runtime/components/Integrations/Sidebar.vue +32 -0
  19. package/dist/runtime/components/Integrations/Sidebar.vue.d.ts +2 -0
  20. package/dist/runtime/components/Integrations/WorkflowEdgeView.d.vue.ts +23 -0
  21. package/dist/runtime/components/Integrations/WorkflowEdgeView.vue +86 -0
  22. package/dist/runtime/components/Integrations/WorkflowEdgeView.vue.d.ts +23 -0
  23. package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +14 -0
  24. package/dist/runtime/components/Integrations/WorkflowEditor.vue +419 -0
  25. package/dist/runtime/components/Integrations/WorkflowEditor.vue.d.ts +14 -0
  26. package/dist/runtime/components/Integrations/WorkflowNodeView.d.vue.ts +11 -0
  27. package/dist/runtime/components/Integrations/WorkflowNodeView.vue +200 -0
  28. package/dist/runtime/components/Integrations/WorkflowNodeView.vue.d.ts +11 -0
  29. package/dist/runtime/components/Integrations/WorkflowTriggerView.d.vue.ts +8 -0
  30. package/dist/runtime/components/Integrations/WorkflowTriggerView.vue +82 -0
  31. package/dist/runtime/components/Integrations/WorkflowTriggerView.vue.d.ts +8 -0
  32. package/dist/runtime/components/Integrations/WorkflowsTable.d.vue.ts +6 -0
  33. package/dist/runtime/components/Integrations/WorkflowsTable.vue +268 -0
  34. package/dist/runtime/components/Integrations/WorkflowsTable.vue.d.ts +6 -0
  35. package/dist/runtime/components/Integrations/workflowLayout.d.ts +17 -0
  36. package/dist/runtime/components/Integrations/workflowLayout.js +29 -0
  37. package/dist/runtime/composables/integrationsApi.d.ts +13 -0
  38. package/dist/runtime/composables/integrationsApi.js +55 -0
  39. package/dist/runtime/composables/useCredentialTypes.d.ts +19 -0
  40. package/dist/runtime/composables/useCredentialTypes.js +47 -0
  41. package/dist/runtime/composables/useIntegrationsAudit.d.ts +26 -0
  42. package/dist/runtime/composables/useIntegrationsAudit.js +39 -0
  43. package/dist/runtime/composables/useIntegrationsCredentials.d.ts +43 -0
  44. package/dist/runtime/composables/useIntegrationsCredentials.js +98 -0
  45. package/dist/runtime/composables/useIntegrationsFocus.d.ts +16 -0
  46. package/dist/runtime/composables/useIntegrationsFocus.js +17 -0
  47. package/dist/runtime/composables/useIntegrationsNodes.d.ts +6 -0
  48. package/dist/runtime/composables/useIntegrationsNodes.js +32 -0
  49. package/dist/runtime/composables/useIntegrationsRuns.d.ts +31 -0
  50. package/dist/runtime/composables/useIntegrationsRuns.js +109 -0
  51. package/dist/runtime/composables/useIntegrationsSchedules.d.ts +14 -0
  52. package/dist/runtime/composables/useIntegrationsSchedules.js +32 -0
  53. package/dist/runtime/composables/useIntegrationsSecrets.d.ts +27 -0
  54. package/dist/runtime/composables/useIntegrationsSecrets.js +76 -0
  55. package/dist/runtime/composables/useIntegrationsTemplates.d.ts +19 -0
  56. package/dist/runtime/composables/useIntegrationsTemplates.js +141 -0
  57. package/dist/runtime/composables/useIntegrationsTriggers.d.ts +39 -0
  58. package/dist/runtime/composables/useIntegrationsTriggers.js +39 -0
  59. package/dist/runtime/composables/useIntegrationsWorkflows.d.ts +28 -0
  60. package/dist/runtime/composables/useIntegrationsWorkflows.js +152 -0
  61. package/dist/runtime/data/integrationNodeCatalog.d.ts +41 -0
  62. package/dist/runtime/data/integrationNodeCatalog.js +67 -0
  63. package/dist/runtime/data/integrationRuns.d.ts +7 -0
  64. package/dist/runtime/data/integrationRuns.js +109 -0
  65. package/dist/runtime/data/integrationTemplates.d.ts +11 -0
  66. package/dist/runtime/data/integrationTemplates.js +9 -0
  67. package/dist/runtime/data/integrationWorkflowSamples.d.ts +18 -0
  68. package/dist/runtime/data/integrationWorkflowSamples.js +318 -0
  69. package/dist/runtime/pages/integrations/audit.d.vue.ts +2 -0
  70. package/dist/runtime/pages/integrations/audit.vue +156 -0
  71. package/dist/runtime/pages/integrations/audit.vue.d.ts +2 -0
  72. package/dist/runtime/pages/integrations/credentials/oauth-complete.d.vue.ts +2 -0
  73. package/dist/runtime/pages/integrations/credentials/oauth-complete.vue +28 -0
  74. package/dist/runtime/pages/integrations/credentials/oauth-complete.vue.d.ts +2 -0
  75. package/dist/runtime/pages/integrations/credentials.d.vue.ts +2 -0
  76. package/dist/runtime/pages/integrations/credentials.vue +403 -0
  77. package/dist/runtime/pages/integrations/credentials.vue.d.ts +2 -0
  78. package/dist/runtime/pages/integrations/index.d.vue.ts +2 -0
  79. package/dist/runtime/pages/integrations/index.vue +226 -0
  80. package/dist/runtime/pages/integrations/index.vue.d.ts +2 -0
  81. package/dist/runtime/pages/integrations/runs.d.vue.ts +2 -0
  82. package/dist/runtime/pages/integrations/runs.vue +100 -0
  83. package/dist/runtime/pages/integrations/runs.vue.d.ts +2 -0
  84. package/dist/runtime/pages/integrations/schedules.d.vue.ts +2 -0
  85. package/dist/runtime/pages/integrations/schedules.vue +111 -0
  86. package/dist/runtime/pages/integrations/schedules.vue.d.ts +2 -0
  87. package/dist/runtime/pages/integrations/secrets.d.vue.ts +2 -0
  88. package/dist/runtime/pages/integrations/secrets.vue +248 -0
  89. package/dist/runtime/pages/integrations/secrets.vue.d.ts +2 -0
  90. package/dist/runtime/pages/integrations/workflows/[id].d.vue.ts +2 -0
  91. package/dist/runtime/pages/integrations/workflows/[id].vue +326 -0
  92. package/dist/runtime/pages/integrations/workflows/[id].vue.d.ts +2 -0
  93. package/dist/runtime/pages/integrations/workflows/index.d.vue.ts +2 -0
  94. package/dist/runtime/pages/integrations/workflows/index.vue +31 -0
  95. package/dist/runtime/pages/integrations/workflows/index.vue.d.ts +2 -0
  96. package/dist/runtime/pages/integrations/workflows/new.d.vue.ts +2 -0
  97. package/dist/runtime/pages/integrations/workflows/new.vue +153 -0
  98. package/dist/runtime/pages/integrations/workflows/new.vue.d.ts +2 -0
  99. package/dist/runtime/types/integrations.d.ts +427 -0
  100. package/dist/runtime/types/integrations.js +0 -0
  101. package/dist/runtime/utils/localize.d.ts +9 -0
  102. package/dist/runtime/utils/localize.js +21 -0
  103. package/dist/runtime/utils/statusStyle.d.ts +15 -0
  104. package/dist/runtime/utils/statusStyle.js +78 -0
  105. package/dist/types.d.mts +9 -0
  106. package/package.json +46 -0
@@ -0,0 +1,39 @@
1
+ import { IntegrationsApiError, useIntegrationsApi } from "./integrationsApi.js";
2
+ export function useIntegrationsTriggers() {
3
+ const all = useState("integrations.triggers.all", () => []);
4
+ const loading = useState("integrations.triggers.loading", () => false);
5
+ const error = useState("integrations.triggers.error", () => null);
6
+ const loaded = useState("integrations.triggers.loaded", () => false);
7
+ const api = useIntegrationsApi();
8
+ const { workflows, load: loadWorkflows } = useIntegrationsWorkflows();
9
+ function unwrapList(res) {
10
+ if (Array.isArray(res)) return res;
11
+ return res?.data ?? [];
12
+ }
13
+ async function list(workflowId) {
14
+ return unwrapList(await api.get(`/workflows/${workflowId}/triggers`));
15
+ }
16
+ async function loadAll(force = false) {
17
+ if (loading.value) return all.value;
18
+ if (loaded.value && !force) return all.value;
19
+ loading.value = true;
20
+ error.value = null;
21
+ try {
22
+ await loadWorkflows();
23
+ const settled = await Promise.allSettled(
24
+ workflows.value.map(async (wf) => (await list(wf.id)).map((t) => ({ ...t, workflowName: wf.name })))
25
+ );
26
+ all.value = settled.flatMap((p) => p.status === "fulfilled" ? p.value : []);
27
+ loaded.value = true;
28
+ } catch (e) {
29
+ error.value = e instanceof IntegrationsApiError ? e.message : e?.message ?? "Could not load triggers.";
30
+ } finally {
31
+ loading.value = false;
32
+ }
33
+ return all.value;
34
+ }
35
+ const create = (workflowId, data) => api.post(`/workflows/${workflowId}/triggers`, data);
36
+ const update = (workflowId, triggerId, data) => api.put(`/workflows/${workflowId}/triggers/${triggerId}`, data);
37
+ const remove = (workflowId, triggerId) => api.del(`/workflows/${workflowId}/triggers/${triggerId}`);
38
+ return { all, loading, error, loaded, list, loadAll, create, update, remove };
39
+ }
@@ -0,0 +1,28 @@
1
+ import type { Workflow, WorkflowBlob, WorkflowExecutionMode } from '../types/integrations.js';
2
+ export declare function useIntegrationsWorkflows(): {
3
+ workflows: any;
4
+ loading: any;
5
+ error: any;
6
+ loaded: any;
7
+ total: import("vue").ComputedRef<any>;
8
+ activeCount: import("vue").ComputedRef<any>;
9
+ load: (force?: boolean) => Promise<Workflow[]>;
10
+ list: () => Promise<Workflow[]>;
11
+ get: (id: number) => Promise<Workflow | null>;
12
+ create: (input: {
13
+ name: string;
14
+ description?: string | null;
15
+ blob: WorkflowBlob;
16
+ active?: boolean;
17
+ executionMode?: WorkflowExecutionMode;
18
+ }) => Promise<Workflow>;
19
+ update: (id: number, patch: {
20
+ name: string;
21
+ description?: string | null;
22
+ blob: WorkflowBlob;
23
+ active: boolean;
24
+ executionMode?: WorkflowExecutionMode;
25
+ }) => Promise<Workflow>;
26
+ remove: (id: number) => Promise<void>;
27
+ toggleActive: (id: number) => Promise<Workflow | null>;
28
+ };
@@ -0,0 +1,152 @@
1
+ import { computed } from "vue";
2
+ import { IntegrationsApiError, useIntegrationsApi } from "./integrationsApi.js";
3
+ const BLOB_VERSION = "v0-draft";
4
+ function toCockpit(api) {
5
+ const apiBlob = api.blob ?? {};
6
+ const triggers = (api.triggers ?? []).map((t) => ({
7
+ id: t.handle ?? String(t.id ?? ""),
8
+ type: t.type,
9
+ name: typeof t.name === "string" ? t.name : t.name ?? void 0,
10
+ active: t.active,
11
+ config: t.config ?? {}
12
+ }));
13
+ const blob = {
14
+ nodeManifestVersion: apiBlob.nodeManifestVersion ?? BLOB_VERSION,
15
+ name: apiBlob.name ?? api.name,
16
+ nodes: apiBlob.nodes ?? [],
17
+ edges: apiBlob.edges ?? [],
18
+ triggerPositions: apiBlob.triggerPositions ?? {},
19
+ triggers
20
+ };
21
+ return {
22
+ id: Number(api.id),
23
+ name: api.name,
24
+ description: api.description ?? null,
25
+ blob_definition_version: BLOB_VERSION,
26
+ blob,
27
+ active: api.active ?? false,
28
+ revision: api.revision ?? 0,
29
+ execution_mode: api.execution_mode,
30
+ created_at: api.created_at ?? "",
31
+ updated_at: api.updated_at ?? ""
32
+ };
33
+ }
34
+ function toPayload(meta) {
35
+ const b = meta.blob;
36
+ return {
37
+ name: meta.name,
38
+ description: meta.description ?? null,
39
+ blob_definition_version: BLOB_VERSION,
40
+ blob: {
41
+ nodeManifestVersion: b.nodeManifestVersion ?? BLOB_VERSION,
42
+ name: typeof b.name === "string" ? b.name : meta.name,
43
+ nodes: b.nodes ?? [],
44
+ edges: b.edges ?? [],
45
+ triggerPositions: b.triggerPositions ?? {}
46
+ },
47
+ active: meta.active,
48
+ execution_mode: meta.executionMode ?? "async_only",
49
+ triggers: (b.triggers ?? []).map((t) => ({
50
+ handle: t.id,
51
+ type: t.type,
52
+ name: (typeof t.name === "string" ? t.name : null) ?? null,
53
+ config: t.type === "webhook" ? { method: "POST", ...t.config ?? {} } : t.config ?? null,
54
+ active: t.active ?? true
55
+ }))
56
+ };
57
+ }
58
+ export function useIntegrationsWorkflows() {
59
+ const workflows = useState("integrations.workflows", () => []);
60
+ const loading = useState("integrations.workflows.loading", () => false);
61
+ const error = useState("integrations.workflows.error", () => null);
62
+ const loaded = useState("integrations.workflows.loaded", () => false);
63
+ const api = useIntegrationsApi();
64
+ function unwrap(res) {
65
+ return res?.data ?? res;
66
+ }
67
+ function captureError(e, fallback) {
68
+ if (e instanceof IntegrationsApiError) return e.message;
69
+ return e?.message ?? fallback;
70
+ }
71
+ function upsertCache(wf) {
72
+ const idx = workflows.value.findIndex((w) => w.id === wf.id);
73
+ workflows.value = idx < 0 ? [...workflows.value, wf] : workflows.value.map((w) => w.id === wf.id ? wf : w);
74
+ }
75
+ async function load(force = false) {
76
+ if (loading.value) return workflows.value;
77
+ if (loaded.value && !force) return workflows.value;
78
+ loading.value = true;
79
+ error.value = null;
80
+ try {
81
+ const list2 = unwrap(await api.get("/workflows")) ?? [];
82
+ workflows.value = list2.map(toCockpit);
83
+ loaded.value = true;
84
+ } catch (e) {
85
+ error.value = captureError(e, "Could not load workflows.");
86
+ } finally {
87
+ loading.value = false;
88
+ }
89
+ return workflows.value;
90
+ }
91
+ async function list() {
92
+ if (!loaded.value) await load();
93
+ return workflows.value;
94
+ }
95
+ async function get(id) {
96
+ try {
97
+ const wf = toCockpit(unwrap(await api.get(`/workflows/${id}`)));
98
+ upsertCache(wf);
99
+ return wf;
100
+ } catch {
101
+ return workflows.value.find((w) => w.id === id) ?? null;
102
+ }
103
+ }
104
+ async function create(input) {
105
+ const wf = toCockpit(unwrap(await api.post("/workflows", toPayload({
106
+ name: input.name,
107
+ description: input.description,
108
+ blob: input.blob,
109
+ active: input.active ?? true,
110
+ executionMode: input.executionMode
111
+ }))));
112
+ upsertCache(wf);
113
+ return wf;
114
+ }
115
+ async function update(id, patch) {
116
+ const wf = toCockpit(unwrap(await api.put(`/workflows/${id}`, toPayload({
117
+ name: patch.name,
118
+ description: patch.description,
119
+ blob: patch.blob,
120
+ active: patch.active,
121
+ executionMode: patch.executionMode
122
+ }))));
123
+ upsertCache(wf);
124
+ return wf;
125
+ }
126
+ async function remove(id) {
127
+ await api.del(`/workflows/${id}`);
128
+ workflows.value = workflows.value.filter((w) => w.id !== id);
129
+ }
130
+ async function toggleActive(id) {
131
+ const wf = workflows.value.find((w) => w.id === id);
132
+ if (!wf) return null;
133
+ return update(id, { name: wf.name, description: wf.description, blob: wf.blob, active: !wf.active, executionMode: wf.execution_mode });
134
+ }
135
+ const total = computed(() => workflows.value.length);
136
+ const activeCount = computed(() => workflows.value.filter((w) => w.active).length);
137
+ return {
138
+ workflows,
139
+ loading,
140
+ error,
141
+ loaded,
142
+ total,
143
+ activeCount,
144
+ load,
145
+ list,
146
+ get,
147
+ create,
148
+ update,
149
+ remove,
150
+ toggleActive
151
+ };
152
+ }
@@ -0,0 +1,41 @@
1
+ import type { NodeManifest, TriggerType } from '../types/integrations.js';
2
+ /**
3
+ * Reactive node-manifest registry — populated ONLY from the live registry
4
+ * (`GET /nodes`, via useIntegrationsNodes). No bundled fallback: either the
5
+ * online registry, or nothing. Consumers read this array directly and
6
+ * `findManifest` resolves against it synchronously, staying reactive to the
7
+ * live update.
8
+ */
9
+ export declare const INTEGRATION_NODE_CATALOG: NodeManifest[];
10
+ /** Replace the catalog contents in place (preserves the reactive identity). */
11
+ export declare function applyNodeCatalog(manifests: NodeManifest[]): void;
12
+ /**
13
+ * Categories rendered in the picker. Colors map to the L.I.D.F.
14
+ * domain palette we use across the cockpit.
15
+ */
16
+ export declare const NODE_CATEGORIES: Array<{
17
+ key: NodeManifest['category'];
18
+ label: string;
19
+ color: string;
20
+ }>;
21
+ export declare function findManifest(slug: string, version?: string): NodeManifest | null;
22
+ export declare const TRIGGER_OUTPUT_PORT = "default";
23
+ export interface TriggerTemplate {
24
+ /** Stable picker id. */
25
+ id: string;
26
+ /** Maps to WorkflowTrigger.type once dropped. */
27
+ type: TriggerType;
28
+ /** Localized display name. */
29
+ name: {
30
+ en: string;
31
+ de: string;
32
+ };
33
+ description: {
34
+ en: string;
35
+ de: string;
36
+ };
37
+ icon: string;
38
+ /** Default config the canvas seeds when the user drops the tile. */
39
+ defaultConfig: Record<string, unknown>;
40
+ }
41
+ export declare const TRIGGER_TEMPLATES: TriggerTemplate[];
@@ -0,0 +1,67 @@
1
+ import { reactive } from "vue";
2
+ export const INTEGRATION_NODE_CATALOG = reactive([]);
3
+ export function applyNodeCatalog(manifests) {
4
+ INTEGRATION_NODE_CATALOG.splice(0, INTEGRATION_NODE_CATALOG.length, ...manifests);
5
+ }
6
+ export const NODE_CATEGORIES = [
7
+ // Slate background everywhere; a faint accent on the icon stroke keeps
8
+ // the categories distinguishable without the rainbow.
9
+ { key: "trigger", label: "Triggers", color: "bg-slate-100 text-emerald-600/80" },
10
+ { key: "action", label: "Actions", color: "bg-slate-100 text-sky-600/80" },
11
+ { key: "io", label: "I/O", color: "bg-slate-100 text-violet-600/80" },
12
+ { key: "transform", label: "Transforms", color: "bg-slate-100 text-amber-700/80" },
13
+ { key: "control", label: "Control flow", color: "bg-slate-100 text-rose-600/80" }
14
+ ];
15
+ export function findManifest(slug, version) {
16
+ const matches = INTEGRATION_NODE_CATALOG.filter((m) => m.slug === slug);
17
+ if (!matches.length) return null;
18
+ if (version) return matches.find((m) => m.version === version) ?? matches[0] ?? null;
19
+ return matches[0] ?? null;
20
+ }
21
+ export const TRIGGER_OUTPUT_PORT = "default";
22
+ export const TRIGGER_TEMPLATES = [
23
+ {
24
+ id: "trigger-manual",
25
+ type: "manual",
26
+ name: { en: "Manual", de: "Manuell" },
27
+ description: {
28
+ en: "Run on demand from the editor or API.",
29
+ de: "Auf Knopfdruck aus dem Editor oder via API."
30
+ },
31
+ icon: "Play",
32
+ defaultConfig: {}
33
+ },
34
+ {
35
+ id: "trigger-schedule",
36
+ type: "schedule",
37
+ name: { en: "Schedule", de: "Zeitplan" },
38
+ description: {
39
+ en: "Cron-based recurring execution.",
40
+ de: "Wiederkehrende Ausf\xFChrung per Cron."
41
+ },
42
+ icon: "Clock",
43
+ defaultConfig: { cron: "0 * * * *", timezone: "Europe/Berlin" }
44
+ },
45
+ {
46
+ id: "trigger-webhook",
47
+ type: "webhook",
48
+ name: { en: "Webhook", de: "Webhook" },
49
+ description: {
50
+ en: "Trigger from an inbound HTTP request.",
51
+ de: "Ausl\xF6sen durch eingehenden HTTP-Aufruf."
52
+ },
53
+ icon: "Webhook",
54
+ defaultConfig: { path: "/incoming", method: "POST" }
55
+ },
56
+ {
57
+ id: "trigger-event",
58
+ type: "event",
59
+ name: { en: "Event", de: "Event" },
60
+ description: {
61
+ en: "Run when a platform event fires (e.g. customer.created).",
62
+ de: "Ausl\xF6sen bei einem Plattform-Event (z. B. customer.created)."
63
+ },
64
+ icon: "Zap",
65
+ defaultConfig: { event_type: "" }
66
+ }
67
+ ];
@@ -0,0 +1,7 @@
1
+ import type { WorkflowRun } from '../types/integrations.js';
2
+ /**
3
+ * Mock execution history. In production this comes from Temporal — workflow
4
+ * status, started/finished, step durations, retry counts, and error messages.
5
+ * Listed newest-first.
6
+ */
7
+ export declare const SAMPLE_RUNS: WorkflowRun[];
@@ -0,0 +1,109 @@
1
+ export const SAMPLE_RUNS = [
2
+ {
3
+ id: "run-01HZX9F8N7",
4
+ workflowId: 1,
5
+ workflowName: "Manual REST GET",
6
+ status: "succeeded",
7
+ triggerId: "manual-1",
8
+ triggerType: "manual",
9
+ startedAt: "2026-05-11T08:14:11Z",
10
+ finishedAt: "2026-05-11T08:14:12Z",
11
+ durationMs: 894,
12
+ steps: [
13
+ { nodeId: "fetch", status: "succeeded", startedAt: "2026-05-11T08:14:11Z", finishedAt: "2026-05-11T08:14:12Z", attempt: 1, durationMs: 850 }
14
+ ]
15
+ },
16
+ {
17
+ id: "run-01HZX8K2C5",
18
+ workflowId: 2,
19
+ workflowName: "Webhook order receiver",
20
+ status: "succeeded",
21
+ triggerId: "stripe-hook",
22
+ triggerType: "webhook",
23
+ startedAt: "2026-05-11T08:08:02Z",
24
+ finishedAt: "2026-05-11T08:08:03Z",
25
+ durationMs: 1244,
26
+ steps: [
27
+ { nodeId: "validate", status: "succeeded", startedAt: "2026-05-11T08:08:02Z", finishedAt: "2026-05-11T08:08:02Z", attempt: 1, durationMs: 12 },
28
+ { nodeId: "forward", status: "succeeded", startedAt: "2026-05-11T08:08:02Z", finishedAt: "2026-05-11T08:08:03Z", attempt: 1, durationMs: 1191 }
29
+ ]
30
+ },
31
+ {
32
+ id: "run-01HZX7Y3D2",
33
+ workflowId: 2,
34
+ workflowName: "Webhook order receiver",
35
+ status: "failed",
36
+ triggerId: "stripe-hook",
37
+ triggerType: "webhook",
38
+ startedAt: "2026-05-11T07:42:17Z",
39
+ finishedAt: "2026-05-11T07:42:25Z",
40
+ durationMs: 7842,
41
+ errorMessage: "fetch failed: 502 Bad Gateway on https://fulfillment.internal/orders after 4 attempts",
42
+ steps: [
43
+ { nodeId: "validate", status: "succeeded", startedAt: "2026-05-11T07:42:17Z", finishedAt: "2026-05-11T07:42:17Z", attempt: 1, durationMs: 9 },
44
+ { nodeId: "forward", status: "failed", startedAt: "2026-05-11T07:42:17Z", finishedAt: "2026-05-11T07:42:24Z", attempt: 4, durationMs: 7820 },
45
+ { nodeId: "notify-failure", status: "succeeded", startedAt: "2026-05-11T07:42:24Z", finishedAt: "2026-05-11T07:42:25Z", attempt: 1, durationMs: 612 }
46
+ ]
47
+ },
48
+ {
49
+ id: "run-01HZX5R7A1",
50
+ workflowId: 3,
51
+ workflowName: "Daily ETL with branching",
52
+ status: "running",
53
+ triggerId: "nightly",
54
+ triggerType: "schedule",
55
+ startedAt: "2026-05-11T08:14:00Z",
56
+ finishedAt: null,
57
+ durationMs: null,
58
+ steps: [
59
+ { nodeId: "fetch", status: "succeeded", startedAt: "2026-05-11T08:14:00Z", finishedAt: "2026-05-11T08:14:02Z", attempt: 1, durationMs: 2100 },
60
+ { nodeId: "route", status: "pending", startedAt: "2026-05-11T08:14:02Z", finishedAt: null, attempt: 1, durationMs: null }
61
+ ]
62
+ },
63
+ {
64
+ id: "run-01HZX4Q8B3",
65
+ workflowId: 3,
66
+ workflowName: "Daily ETL with branching",
67
+ status: "succeeded",
68
+ triggerId: "nightly",
69
+ triggerType: "schedule",
70
+ startedAt: "2026-05-10T03:00:00Z",
71
+ finishedAt: "2026-05-10T03:00:21Z",
72
+ durationMs: 21344,
73
+ steps: [
74
+ { nodeId: "fetch", status: "succeeded", startedAt: "2026-05-10T03:00:00Z", finishedAt: "2026-05-10T03:00:02Z", attempt: 1, durationMs: 2050 },
75
+ { nodeId: "route", status: "succeeded", startedAt: "2026-05-10T03:00:02Z", finishedAt: "2026-05-10T03:00:02Z", attempt: 1, durationMs: 8 },
76
+ { nodeId: "ship", status: "succeeded", startedAt: "2026-05-10T03:00:02Z", finishedAt: "2026-05-10T03:00:21Z", attempt: 1, durationMs: 19200 }
77
+ ]
78
+ },
79
+ {
80
+ id: "run-01HZX3M2E6",
81
+ workflowId: 1,
82
+ workflowName: "Manual REST GET",
83
+ status: "failed",
84
+ triggerId: "manual-1",
85
+ triggerType: "manual",
86
+ startedAt: "2026-05-10T16:11:00Z",
87
+ finishedAt: "2026-05-10T16:11:34Z",
88
+ durationMs: 33812,
89
+ errorMessage: "timeout exceeded after 30s on https://api.example.com/health",
90
+ steps: [
91
+ { nodeId: "fetch", status: "failed", startedAt: "2026-05-10T16:11:00Z", finishedAt: "2026-05-10T16:11:34Z", attempt: 3, durationMs: 33800 }
92
+ ]
93
+ },
94
+ {
95
+ id: "run-01HZX2N9F4",
96
+ workflowId: 2,
97
+ workflowName: "Webhook order receiver",
98
+ status: "succeeded",
99
+ triggerId: "stripe-hook",
100
+ triggerType: "webhook",
101
+ startedAt: "2026-05-10T11:33:48Z",
102
+ finishedAt: "2026-05-10T11:33:49Z",
103
+ durationMs: 942,
104
+ steps: [
105
+ { nodeId: "validate", status: "succeeded", startedAt: "2026-05-10T11:33:48Z", finishedAt: "2026-05-10T11:33:48Z", attempt: 1, durationMs: 8 },
106
+ { nodeId: "forward", status: "succeeded", startedAt: "2026-05-10T11:33:48Z", finishedAt: "2026-05-10T11:33:49Z", attempt: 1, durationMs: 901 }
107
+ ]
108
+ }
109
+ ];
@@ -0,0 +1,11 @@
1
+ import type { WorkflowTemplate } from '../types/integrations.js';
2
+ /**
3
+ * Category lens config for the Templates catalogue. The templates themselves
4
+ * come live from the Integrations registry (`GET /templates`) — there is no
5
+ * mock catalogue; an empty registry is an empty catalogue.
6
+ */
7
+ export declare const TEMPLATE_CATEGORIES: Array<{
8
+ key: WorkflowTemplate['category'];
9
+ label: string;
10
+ color: string;
11
+ }>;
@@ -0,0 +1,9 @@
1
+ export const TEMPLATE_CATEGORIES = [
2
+ // Uniform muted pill — the label carries the meaning, no rainbow needed.
3
+ { key: "sync", label: "Sync", color: "bg-slate-100 text-slate-700" },
4
+ { key: "notification", label: "Notification", color: "bg-slate-100 text-slate-700" },
5
+ { key: "fulfilment", label: "Fulfilment", color: "bg-slate-100 text-slate-700" },
6
+ { key: "enrichment", label: "Enrichment", color: "bg-slate-100 text-slate-700" },
7
+ { key: "finance", label: "Finance", color: "bg-slate-100 text-slate-700" },
8
+ { key: "reporting", label: "Reporting", color: "bg-slate-100 text-slate-700" }
9
+ ];
@@ -0,0 +1,18 @@
1
+ import type { Connection, ConnectionTemplate, Workflow } from '../types/integrations.js';
2
+ /**
3
+ * Seed data for the workflow list. Built strictly with the manifests the
4
+ * backend currently has fixtures for (`rest-get`, `control-if`,
5
+ * `control-switch`) and the trigger output port the reference workflow
6
+ * blobs use (`default` — see
7
+ * `playground/integrations/tests/Fixtures/WorkflowBlobs/*.json`).
8
+ *
9
+ * If you change a manifest's `slug` / `version`, change it here too.
10
+ */
11
+ export declare const SAMPLE_WORKFLOWS: Workflow[];
12
+ export declare const SAMPLE_SECRETS: {
13
+ key: string;
14
+ created_at: string;
15
+ updated_at: string;
16
+ }[];
17
+ export declare const CONNECTION_TEMPLATES: ConnectionTemplate[];
18
+ export declare const SAMPLE_CONNECTIONS: Connection[];