@revenexx/studio-integrations 0.6.0 → 1.0.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 (137) hide show
  1. package/CHANGELOG.md +643 -0
  2. package/README.md +31 -0
  3. package/dist/module.d.mts +17 -1
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +12 -3
  6. package/dist/runtime/components/Integrations/CredentialCreateDialog.vue +32 -28
  7. package/dist/runtime/components/Integrations/CredentialDetailDialog.vue +45 -38
  8. package/dist/runtime/components/Integrations/CredentialRevenexxSource.vue +58 -58
  9. package/dist/runtime/components/Integrations/CredentialTypePicker.vue +10 -9
  10. package/dist/runtime/components/Integrations/DeadLettersPanel.vue +18 -17
  11. package/dist/runtime/components/Integrations/EventTypeCombobox.vue +4 -3
  12. package/dist/runtime/components/Integrations/ExpressionInput.vue +21 -15
  13. package/dist/runtime/components/Integrations/GroupFrameView.vue +29 -19
  14. package/dist/runtime/components/Integrations/Layout.vue +28 -3
  15. package/dist/runtime/components/Integrations/NodeConfigDynamicField.d.vue.ts +3 -0
  16. package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue +30 -16
  17. package/dist/runtime/components/Integrations/NodeConfigDynamicField.vue.d.ts +3 -0
  18. package/dist/runtime/components/Integrations/NodeConfigDynamicSchema.vue +10 -8
  19. package/dist/runtime/components/Integrations/NodeConfigField.d.vue.ts +3 -0
  20. package/dist/runtime/components/Integrations/NodeConfigField.vue +45 -42
  21. package/dist/runtime/components/Integrations/NodeConfigField.vue.d.ts +3 -0
  22. package/dist/runtime/components/Integrations/NodeInspector.d.vue.ts +2 -2
  23. package/dist/runtime/components/Integrations/NodeInspector.vue +315 -221
  24. package/dist/runtime/components/Integrations/NodeInspector.vue.d.ts +2 -2
  25. package/dist/runtime/components/Integrations/NodeOutputSchema.d.vue.ts +2 -1
  26. package/dist/runtime/components/Integrations/NodeOutputSchema.vue +37 -10
  27. package/dist/runtime/components/Integrations/NodeOutputSchema.vue.d.ts +2 -1
  28. package/dist/runtime/components/Integrations/NodePalette.vue +40 -35
  29. package/dist/runtime/components/Integrations/QueryBuilder.vue +44 -43
  30. package/dist/runtime/components/Integrations/RunActionsMenu.vue +36 -12
  31. package/dist/runtime/components/Integrations/RunDetailPanel.vue +114 -62
  32. package/dist/runtime/components/Integrations/RunPayloadInput.vue +14 -13
  33. package/dist/runtime/components/Integrations/RunResponseModal.vue +11 -10
  34. package/dist/runtime/components/Integrations/RunsTable.d.vue.ts +0 -1
  35. package/dist/runtime/components/Integrations/RunsTable.vue +38 -16
  36. package/dist/runtime/components/Integrations/RunsTable.vue.d.ts +0 -1
  37. package/dist/runtime/components/Integrations/SftpAccountImportDialog.vue +8 -7
  38. package/dist/runtime/components/Integrations/Sidebar.vue +14 -10
  39. package/dist/runtime/components/Integrations/StickyNoteView.d.vue.ts +14 -4
  40. package/dist/runtime/components/Integrations/StickyNoteView.vue +82 -34
  41. package/dist/runtime/components/Integrations/StickyNoteView.vue.d.ts +14 -4
  42. package/dist/runtime/components/Integrations/SurfaceCard.d.vue.ts +50 -0
  43. package/dist/runtime/components/Integrations/SurfaceCard.vue +55 -0
  44. package/dist/runtime/components/Integrations/SurfaceCard.vue.d.ts +50 -0
  45. package/dist/runtime/components/Integrations/TemplateCard.vue +18 -8
  46. package/dist/runtime/components/Integrations/TemplateFlowPreview.vue +22 -12
  47. package/dist/runtime/components/Integrations/WorkflowContextMenu.vue +34 -33
  48. package/dist/runtime/components/Integrations/WorkflowCreateDialog.vue +41 -39
  49. package/dist/runtime/components/Integrations/WorkflowDuplicateDialog.vue +8 -7
  50. package/dist/runtime/components/Integrations/WorkflowEdgeView.vue +6 -4
  51. package/dist/runtime/components/Integrations/WorkflowEditor.d.vue.ts +16 -0
  52. package/dist/runtime/components/Integrations/WorkflowEditor.vue +131 -87
  53. package/dist/runtime/components/Integrations/WorkflowEditor.vue.d.ts +16 -0
  54. package/dist/runtime/components/Integrations/WorkflowHistoryPanel.d.vue.ts +6 -0
  55. package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue +27 -24
  56. package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue.d.ts +6 -0
  57. package/dist/runtime/components/Integrations/WorkflowIconPicker.vue +7 -6
  58. package/dist/runtime/components/Integrations/WorkflowNodeView.vue +76 -46
  59. package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue +55 -43
  60. package/dist/runtime/components/Integrations/WorkflowSettingsDialog.d.vue.ts +16 -17
  61. package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue +55 -43
  62. package/dist/runtime/components/Integrations/WorkflowSettingsDialog.vue.d.ts +16 -17
  63. package/dist/runtime/components/Integrations/WorkflowTagsInput.vue +9 -8
  64. package/dist/runtime/components/Integrations/WorkflowTriggerView.vue +15 -13
  65. package/dist/runtime/components/Integrations/WorkflowVariablesDialog.vue +79 -39
  66. package/dist/runtime/components/Integrations/WorkflowsTable.vue +83 -45
  67. package/dist/runtime/composables/integrationsApi.js +4 -2
  68. package/dist/runtime/composables/useCredentialTypes.js +4 -2
  69. package/dist/runtime/composables/useIntegrationsCredentials.d.ts +11 -0
  70. package/dist/runtime/composables/useIntegrationsCredentials.js +8 -6
  71. package/dist/runtime/composables/useIntegrationsFocus.d.ts +12 -0
  72. package/dist/runtime/composables/useIntegrationsLocale.d.ts +26 -0
  73. package/dist/runtime/composables/useIntegrationsLocale.js +8 -0
  74. package/dist/runtime/composables/useIntegrationsNodes.js +14 -2
  75. package/dist/runtime/composables/useIntegrationsRealtime.d.ts +149 -0
  76. package/dist/runtime/composables/useIntegrationsRealtime.js +80 -0
  77. package/dist/runtime/composables/useIntegrationsRevisions.js +9 -7
  78. package/dist/runtime/composables/useIntegrationsRuns.d.ts +1 -1
  79. package/dist/runtime/composables/useIntegrationsRuns.js +3 -1
  80. package/dist/runtime/composables/useIntegrationsSchedules.d.ts +3 -2
  81. package/dist/runtime/composables/useIntegrationsSecrets.js +4 -2
  82. package/dist/runtime/composables/useIntegrationsT.d.ts +35 -0
  83. package/dist/runtime/composables/useIntegrationsT.js +9 -0
  84. package/dist/runtime/composables/useIntegrationsTemplates.d.ts +3 -3
  85. package/dist/runtime/composables/useIntegrationsTemplates.js +16 -8
  86. package/dist/runtime/composables/useIntegrationsTriggers.d.ts +23 -3
  87. package/dist/runtime/composables/useIntegrationsTriggers.js +21 -8
  88. package/dist/runtime/composables/useIntegrationsWorkflows.d.ts +10 -1
  89. package/dist/runtime/composables/useIntegrationsWorkflows.js +30 -7
  90. package/dist/runtime/composables/useNodeConfigResolve.js +4 -2
  91. package/dist/runtime/data/integrationNodeCatalog.d.ts +63 -1
  92. package/dist/runtime/data/integrationNodeCatalog.js +22 -4
  93. package/dist/runtime/data/integrationTemplates.d.ts +9 -0
  94. package/dist/runtime/data/integrationTemplates.js +7 -1
  95. package/dist/runtime/data/nodeInputData.d.ts +58 -1
  96. package/dist/runtime/data/nodeInputData.js +30 -5
  97. package/dist/runtime/data/payloadForm.js +2 -1
  98. package/dist/runtime/data/triggerGlyphs.d.ts +47 -0
  99. package/dist/runtime/data/triggerGlyphs.js +11 -0
  100. package/dist/runtime/data/workflowIconCatalog.js +2 -1
  101. package/dist/runtime/i18n/messages/de.json +1224 -0
  102. package/dist/runtime/i18n/messages/en.json +1224 -0
  103. package/dist/runtime/i18n/translate.d.ts +83 -0
  104. package/dist/runtime/i18n/translate.js +41 -0
  105. package/dist/runtime/pages/integrations/audit.vue +52 -34
  106. package/dist/runtime/pages/integrations/credentials/oauth-complete.vue +3 -2
  107. package/dist/runtime/pages/integrations/credentials.vue +73 -52
  108. package/dist/runtime/pages/integrations/index.vue +66 -73
  109. package/dist/runtime/pages/integrations/runs.vue +33 -21
  110. package/dist/runtime/pages/integrations/schedules.vue +49 -28
  111. package/dist/runtime/pages/integrations/secrets.vue +34 -34
  112. package/dist/runtime/pages/integrations/templates/[slug].vue +89 -72
  113. package/dist/runtime/pages/integrations/templates/index.vue +35 -27
  114. package/dist/runtime/pages/integrations/workflows/[id].vue +351 -197
  115. package/dist/runtime/pages/integrations/workflows/index.vue +10 -5
  116. package/dist/runtime/plugins/locale.d.ts +10 -0
  117. package/dist/runtime/plugins/locale.js +6 -0
  118. package/dist/runtime/plugins/realtime.client.d.ts +32 -0
  119. package/dist/runtime/plugins/realtime.client.js +4 -0
  120. package/dist/runtime/types/integrations.d.ts +25 -1
  121. package/dist/runtime/utils/cockpitSources.d.ts +22 -3
  122. package/dist/runtime/utils/credentialState.d.ts +30 -2
  123. package/dist/runtime/utils/credentialState.js +26 -11
  124. package/dist/runtime/utils/localize.d.ts +52 -5
  125. package/dist/runtime/utils/localize.js +47 -9
  126. package/dist/runtime/utils/pollBudget.d.ts +72 -0
  127. package/dist/runtime/utils/pollBudget.js +17 -0
  128. package/dist/runtime/utils/schedule.d.ts +0 -25
  129. package/dist/runtime/utils/schedule.js +37 -25
  130. package/dist/runtime/utils/servedPaths.d.ts +22 -0
  131. package/dist/runtime/utils/servedPaths.js +3 -0
  132. package/dist/runtime/utils/statusStyle.d.ts +26 -2
  133. package/dist/runtime/utils/statusStyle.js +9 -1
  134. package/dist/runtime/utils/validationFindings.d.ts +2 -2
  135. package/dist/runtime/utils/validationFindings.js +4 -3
  136. package/dist/types.d.mts +2 -6
  137. package/package.json +3 -2
@@ -1,4 +1,14 @@
1
- const DAY_NAMES = ["Sundays", "Mondays", "Tuesdays", "Wednesdays", "Thursdays", "Fridays", "Saturdays"];
1
+ import { useIntegrationsT } from "../composables/useIntegrationsT.js";
2
+ import { studioLocale } from "./localize.js";
3
+ const WEEKDAY_KEYS = [
4
+ "integration.schedules.cron.weekday.sunday",
5
+ "integration.schedules.cron.weekday.monday",
6
+ "integration.schedules.cron.weekday.tuesday",
7
+ "integration.schedules.cron.weekday.wednesday",
8
+ "integration.schedules.cron.weekday.thursday",
9
+ "integration.schedules.cron.weekday.friday",
10
+ "integration.schedules.cron.weekday.saturday"
11
+ ];
2
12
  export const PLATFORM_TIMEZONE = "UTC";
3
13
  export function scheduleTimezone(timezone) {
4
14
  return typeof timezone === "string" && timezone.trim() !== "" ? timezone.trim() : PLATFORM_TIMEZONE;
@@ -126,54 +136,56 @@ export function toCron(r) {
126
136
  function at(hour, minute) {
127
137
  return `${String(hour).padStart(2, "0")}:${String(minute).padStart(2, "0")}`;
128
138
  }
129
- function plural(n, unit) {
130
- return `${n} ${unit}${n === 1 ? "" : "s"}`;
131
- }
132
139
  function ordinal(n) {
140
+ if (studioLocale().split("-")[0] === "de") return `${n}.`;
133
141
  const suffix = n % 100 >= 11 && n % 100 <= 13 ? "th" : ["th", "st", "nd", "rd"][n % 10] ?? "th";
134
142
  return `${n}${suffix}`;
135
143
  }
136
144
  function sameDays(days, other) {
137
145
  return days.length === other.length && days.every((d) => other.includes(d));
138
146
  }
139
- function listWords(words) {
147
+ function listWords(words, t) {
140
148
  if (words.length <= 1) return words[0] ?? "";
141
- return `${words.slice(0, -1).join(", ")} and ${words[words.length - 1]}`;
149
+ return `${words.slice(0, -1).join(", ")} ${t("integration.common.list.and")} ${words[words.length - 1]}`;
150
+ }
151
+ function isEveryDay(days) {
152
+ if (!days) return true;
153
+ const set = new Set(days.map((d) => d === 7 ? 0 : d));
154
+ return set.size === 0 || set.size === 7;
142
155
  }
143
- function dayPhrase(days) {
144
- if (!days) return "Daily";
145
- const set = [...new Set(days.map((d) => d === 7 ? 0 : d))].sort((a, b) => a - b);
146
- if (!set.length || set.length === 7) return "Daily";
147
- if (sameDays(set, WEEKDAYS)) return "Weekdays";
148
- if (sameDays(set, WEEKEND)) return "Weekends";
149
- return listWords(set.map((d) => DAY_NAMES[d] ?? "").filter(Boolean));
156
+ function dayPhrase(days, t) {
157
+ if (isEveryDay(days)) return t("integration.schedules.cron.day.daily");
158
+ const set = [...new Set((days ?? []).map((d) => d === 7 ? 0 : d))].sort((a, b) => a - b);
159
+ if (sameDays(set, WEEKDAYS)) return t("integration.schedules.cron.day.weekdays");
160
+ if (sameDays(set, WEEKEND)) return t("integration.schedules.cron.day.weekends");
161
+ return listWords(set.map((d) => t(WEEKDAY_KEYS[d])), t);
150
162
  }
151
163
  export function describeRecurrence(r) {
164
+ const t = useIntegrationsT();
152
165
  switch (r.kind) {
153
166
  case "minutes":
154
- return r.interval <= 1 ? "Every minute" : `Every ${plural(r.interval, "minute")}`;
167
+ return r.interval <= 1 ? t("integration.schedules.cron.everyMinute") : t("integration.schedules.cron.everyNMinutes", { n: r.interval });
155
168
  case "hourly":
156
- return r.minute === 0 ? "Hourly, on the hour" : `Hourly at :${String(r.minute).padStart(2, "0")}`;
169
+ return r.minute === 0 ? t("integration.schedules.cron.hourlyOnTheHour") : t("integration.schedules.cron.hourlyAt", { minute: String(r.minute).padStart(2, "0") });
157
170
  case "hours":
158
171
  if (r.interval <= 1) return describeRecurrence({ kind: "hourly", minute: r.minute });
159
- return r.minute === 0 ? `Every ${plural(r.interval, "hour")}, on the hour` : `Every ${plural(r.interval, "hour")} at :${String(r.minute).padStart(2, "0")}`;
172
+ return r.minute === 0 ? t("integration.schedules.cron.everyNHoursOnTheHour", { n: r.interval }) : t("integration.schedules.cron.everyNHoursAt", { n: r.interval, minute: String(r.minute).padStart(2, "0") });
160
173
  case "daily":
161
- return `Daily at ${at(r.hour, r.minute)}`;
174
+ return t("integration.schedules.cron.dailyAt", { time: at(r.hour, r.minute) });
162
175
  case "times": {
163
176
  const hours = [...new Set(r.hours)].sort((a, b) => a - b);
164
177
  if (hours.length < 2) return describeRecurrence({ kind: "weekly", days: r.days ?? [0, 1, 2, 3, 4, 5, 6], hour: hours[0] ?? 0, minute: r.minute });
165
- const phrase = dayPhrase(r.days);
166
178
  if (saysAsSpan(hours)) {
167
- const span = `hourly from ${at(hours[0], r.minute)} to ${at(hours[hours.length - 1], r.minute)}`;
168
- return phrase === "Daily" ? `Hourly from ${at(hours[0], r.minute)} to ${at(hours[hours.length - 1], r.minute)}` : `${phrase}, ${span}`;
179
+ const from = at(hours[0], r.minute);
180
+ const to = at(hours[hours.length - 1], r.minute);
181
+ return isEveryDay(r.days) ? t("integration.schedules.cron.spanAllDay", { from, to }) : t("integration.schedules.cron.spanWithDays", { days: dayPhrase(r.days, t), from, to });
169
182
  }
170
- return `${phrase} at ${listWords(hours.map((h) => at(h, r.minute)))}`;
171
- }
172
- case "weekly": {
173
- return `${dayPhrase(r.days)} at ${at(r.hour, r.minute)}`;
183
+ return t("integration.schedules.cron.namedTimes", { days: dayPhrase(r.days, t), times: listWords(hours.map((h) => at(h, r.minute)), t) });
174
184
  }
185
+ case "weekly":
186
+ return t("integration.schedules.cron.weeklyAt", { days: dayPhrase(r.days, t), time: at(r.hour, r.minute) });
175
187
  case "monthly":
176
- return `Monthly on the ${ordinal(r.day)}, at ${at(r.hour, r.minute)}`;
188
+ return t("integration.schedules.cron.monthlyAt", { ordinal: ordinal(r.day), time: at(r.hour, r.minute) });
177
189
  }
178
190
  }
179
191
  export function describeCron(cron) {
@@ -0,0 +1,22 @@
1
+ /**
2
+ * The `/integrations/…` paths a host actually serves, out of the route records its
3
+ * router hands back.
4
+ *
5
+ * The dashboard's four shortcuts into Import & Export, the SFTP server, the event
6
+ * stream and inbound webhooks point at pages this module does not have — they are
7
+ * the host's (PO-223, [`docs/host-surfaces.md`](../../../docs/host-surfaces.md)) —
8
+ * so each card is offered as a way in only where the host has the path.
9
+ *
10
+ * It lives here rather than in the page for the same reason `scanRoutes` lives in
11
+ * `src/pageRoutes.ts`: the trailing-slash strip and the decision to compare exactly
12
+ * are what the doc names as the *misinforming* failure mode, and prose does not
13
+ * fail. `servedPaths.test.ts` pins the three cases that matter.
14
+ *
15
+ * **Exact strings, deliberately.** A parametrised page registers
16
+ * `/integrations/:surface`, and a route-prefixing i18n strategy registers
17
+ * `/en/integrations/io`; neither is one of the four literals, so a host built that
18
+ * way is told its own surfaces live elsewhere. That is the documented limit of the
19
+ * question — narrower than resolving through the matcher, which a host with a
20
+ * catch-all page answers "yes" to everywhere.
21
+ */
22
+ export declare function servedPaths(routePaths: string[]): Set<string>;
@@ -0,0 +1,3 @@
1
+ export function servedPaths(routePaths) {
2
+ return new Set(routePaths.map((path) => path.replace(/\/$/, "")));
3
+ }
@@ -13,9 +13,33 @@ export declare function statusTone(status: string | null | undefined): StatusTon
13
13
  export declare function statusClass(status: string | null | undefined): string;
14
14
  /** Tone classes directly (when you already have a tone). */
15
15
  export declare function toneClass(tone: StatusTone): string;
16
+ /** The run-status words the studio itself displays (as opposed to whatever
17
+ * vocabulary Temporal or the raw API used to get there) — the only ones
18
+ * `runStatusLabel` translates. Anything else passes through unlabelled: a
19
+ * status this catalogue doesn't know is a raw field, not the studio's chrome.
20
+ *
21
+ * An array rather than a set, and exported, because the runs list offers these
22
+ * five as the choices it can be narrowed to and has to offer them in a fixed
23
+ * order. It used to keep its own copy of the list, so a sixth word added here
24
+ * would have been labelled everywhere and silently missing from that menu. */
25
+ export declare const RUN_STATUS_WORDS: readonly ["running", "succeeded", "failed", "cancelled", "queued"];
16
26
  /**
17
27
  * Raw API/Temporal run vocabulary → the cockpit's run-status labels, so a run
18
- * never reads "completed" in one surface and "succeeded" in another. Unknown
19
- * statuses pass through lowercased.
28
+ * never reads "completed" in one surface and "succeeded" in another. This IS
29
+ * the studio's own chrome (Temporal's "completed" becomes our "succeeded"), so
30
+ * unlike a raw `run.status` read elsewhere, it is translated. Unknown statuses
31
+ * still pass through lowercased, untranslated — this function only relabels
32
+ * the fixed run-status vocabulary, not arbitrary strings.
33
+ */
34
+ /**
35
+ * The platform's run vocabulary reduced to the studio's own five words — Temporal's
36
+ * `completed` is our `succeeded`, `pending` is `queued`, and two ways of dying are
37
+ * both `failed`. A status this catalogue does not know comes back as itself.
38
+ *
39
+ * Exported because a run's status is used as an *identity* as well as a word: the runs
40
+ * list narrows by it, and what a filter stores has to be something that does not move
41
+ * when the reader's language does. Both sides read this, so a filter and a row can
42
+ * never disagree about which status they mean.
20
43
  */
44
+ export declare function normalisedRunStatus(status: string | null | undefined): string;
21
45
  export declare function runStatusLabel(status: string | null | undefined): string;
@@ -76,7 +76,9 @@ export function statusClass(status) {
76
76
  export function toneClass(tone) {
77
77
  return TONE_CLASS[tone];
78
78
  }
79
- export function runStatusLabel(status) {
79
+ export const RUN_STATUS_WORDS = ["running", "succeeded", "failed", "cancelled", "queued"];
80
+ const RUN_STATUS_WORD_SET = new Set(RUN_STATUS_WORDS);
81
+ export function normalisedRunStatus(status) {
80
82
  if (!status) return "";
81
83
  const s = String(status).toLowerCase().replace(/[\s-]+/g, "_");
82
84
  switch (s) {
@@ -91,3 +93,9 @@ export function runStatusLabel(status) {
91
93
  return s;
92
94
  }
93
95
  }
96
+ export function runStatusLabel(status) {
97
+ const normalized = normalisedRunStatus(status);
98
+ if (!normalized) return "";
99
+ if (!RUN_STATUS_WORD_SET.has(normalized)) return normalized;
100
+ return useIntegrationsT()(`integration.runs.status.${normalized}`);
101
+ }
@@ -2,7 +2,7 @@ import type { WorkflowNode } from '../types/integrations.js';
2
2
  /**
3
3
  * Reading the backend's validation findings — for the editor's validation
4
4
  * banner (behavior specs/workflow-validation.md, how docs/workflow-validation.md)
5
- * and for the node configuration dialog (specs/node-inspector.md AC-8).
5
+ * and for the node configuration dialog (specs/node-configuration.md AC-8).
6
6
  *
7
7
  * The backend reports one finding per incomplete setting, each keyed by its
8
8
  * blob path (`blob.nodes.4.config.companyId`). The two readers want different
@@ -74,7 +74,7 @@ export declare function findingFieldKey(path: string): string | null;
74
74
  export declare function groupFindingsByNode(findings: readonly ValidationFinding[], nodes: readonly WorkflowNode[], labelOf?: (node: WorkflowNode) => string): FindingNodeGroup[];
75
75
  /**
76
76
  * Node id → config key → the message to show AT that setting
77
- * (specs/node-inspector.md AC-8).
77
+ * (specs/node-configuration.md AC-8).
78
78
  *
79
79
  * First finding wins: the backend reports the most specific reason first, and
80
80
  * two sentences stacked under one input would be noise.
@@ -1,3 +1,4 @@
1
+ import { useIntegrationsT } from "../composables/useIntegrationsT.js";
1
2
  import { findManifest } from "../data/integrationNodeCatalog.js";
2
3
  import { resolveLocalized } from "./localize.js";
3
4
  export function nodeDisplayLabel(node) {
@@ -47,7 +48,7 @@ export function findingsByNodeField(findings, nodes) {
47
48
  return out;
48
49
  }
49
50
  export function findingsSummary(findingCount, nodeCount) {
50
- const settings = `${findingCount} setting${findingCount === 1 ? "" : "s"}`;
51
- const inNodes = nodeCount ? ` in ${nodeCount} node${nodeCount === 1 ? "" : "s"}` : "";
52
- return `${settings}${inNodes} still need${findingCount === 1 ? "s" : ""} fixing`;
51
+ const t = useIntegrationsT();
52
+ const nodesClause = nodeCount ? ` ${t("integration.workflows.validation.summary.nodesClause", nodeCount)}` : "";
53
+ return t("integration.workflows.validation.summary", findingCount, { nodesClause });
53
54
  }
package/dist/types.d.mts CHANGED
@@ -1,9 +1,5 @@
1
- import type { NuxtModule } from '@nuxt/schema'
2
-
3
- import type { default as Module } from './module.mjs'
4
-
5
- export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<O> : Record<string, any>
6
-
7
1
  export { default } from './module.mjs'
8
2
 
3
+ export { type ModuleOptions } from './module.mjs'
4
+
9
5
  export * from '../dist/runtime/types/integrations.js'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revenexx/studio-integrations",
3
- "version": "0.6.0",
3
+ "version": "1.0.0",
4
4
  "type": "module",
5
5
  "description": "Integration Studio (core: workflows, node editor, runs, schedules, credentials, secrets, audit) as a standalone, publishable Nuxt module.",
6
6
  "repository": {
@@ -26,7 +26,7 @@
26
26
  },
27
27
  "dependencies": {
28
28
  "@nuxt/kit": "^4.0.0",
29
- "@revenexx/studio-shared": "^0.2.0",
29
+ "@revenexx/studio-shared": "^0.3.0",
30
30
  "@solar-icons/nuxt": "^1.2.0",
31
31
  "marked": "^18.0.5"
32
32
  },
@@ -55,6 +55,7 @@
55
55
  "@nuxt/module-builder": "^1.0.2",
56
56
  "@playwright/test": "^1.57.0",
57
57
  "@nuxt/kit": "^4.0.0",
58
+ "@revenexx/talkback-js": "^0.3.0",
58
59
  "@nuxt/schema": "^4.0.0",
59
60
  "nuxt": "^4.2.2",
60
61
  "vitest": "^3.2.0",