@revenexx/studio-integrations 2.8.1 → 2.10.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 (50) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/module.json +2 -2
  3. package/dist/runtime/components/Integrations/ExpressionInput.vue +31 -0
  4. package/dist/runtime/components/Integrations/NodeConfigField.vue +5 -1
  5. package/dist/runtime/components/Integrations/NodePalette.vue +75 -71
  6. package/dist/runtime/components/Integrations/RunDetailPanel.vue +11 -5
  7. package/dist/runtime/components/Integrations/TemplateInstallStep.vue +2 -2
  8. package/dist/runtime/components/Integrations/WorkflowEdgeView.d.vue.ts +6 -0
  9. package/dist/runtime/components/Integrations/WorkflowEdgeView.vue +4 -2
  10. package/dist/runtime/components/Integrations/WorkflowEdgeView.vue.d.ts +6 -0
  11. package/dist/runtime/components/Integrations/WorkflowEditor.vue +147 -27
  12. package/dist/runtime/components/Integrations/WorkflowHistoryPanel.vue +36 -12
  13. package/dist/runtime/components/Integrations/WorkflowNodeView.d.vue.ts +14 -0
  14. package/dist/runtime/components/Integrations/WorkflowNodeView.vue +170 -13
  15. package/dist/runtime/components/Integrations/WorkflowNodeView.vue.d.ts +14 -0
  16. package/dist/runtime/components/Integrations/WorkflowRunReplayPanel.vue +34 -12
  17. package/dist/runtime/components/Integrations/WorkflowTriggerView.d.vue.ts +8 -1
  18. package/dist/runtime/components/Integrations/WorkflowTriggerView.vue +3 -1
  19. package/dist/runtime/components/Integrations/WorkflowTriggerView.vue.d.ts +8 -1
  20. package/dist/runtime/components/Integrations/canvasSides.d.ts +27 -0
  21. package/dist/runtime/components/Integrations/canvasSides.js +22 -0
  22. package/dist/runtime/composables/useIntegrationsCredentials.d.ts +4 -1
  23. package/dist/runtime/composables/useIntegrationsCredentials.js +8 -3
  24. package/dist/runtime/data/canvasShapes.d.ts +139 -0
  25. package/dist/runtime/data/canvasShapes.js +130 -0
  26. package/dist/runtime/data/connectionRules.d.ts +110 -0
  27. package/dist/runtime/data/connectionRules.js +110 -0
  28. package/dist/runtime/data/graphShapes.d.ts +175 -0
  29. package/dist/runtime/data/graphShapes.js +359 -0
  30. package/dist/runtime/data/handleId.d.ts +12 -0
  31. package/dist/runtime/data/handleId.js +3 -0
  32. package/dist/runtime/data/integrationTemplates.js +3 -4
  33. package/dist/runtime/data/refusalMessage.d.ts +32 -0
  34. package/dist/runtime/data/refusalMessage.js +42 -0
  35. package/dist/runtime/data/saveRefusal.d.ts +31 -0
  36. package/dist/runtime/data/saveRefusal.js +25 -0
  37. package/dist/runtime/i18n/messages/de.json +36 -1
  38. package/dist/runtime/i18n/messages/en.json +36 -1
  39. package/dist/runtime/pages/integrations/schedules.vue +1 -1
  40. package/dist/runtime/pages/integrations/workflows/[id].vue +38 -3
  41. package/dist/runtime/types/integrations.d.ts +13 -4
  42. package/dist/runtime/utils/apiError.js +7 -4
  43. package/dist/runtime/utils/packageLabel.d.ts +17 -0
  44. package/dist/runtime/utils/packageLabel.js +6 -0
  45. package/dist/runtime/utils/skippedStep.d.ts +39 -0
  46. package/dist/runtime/utils/skippedStep.js +22 -0
  47. package/package.json +3 -3
  48. package/dist/runtime/components/Integrations/NodeLogo.d.vue.ts +0 -21
  49. package/dist/runtime/components/Integrations/NodeLogo.vue +0 -10
  50. package/dist/runtime/components/Integrations/NodeLogo.vue.d.ts +0 -21
@@ -77,7 +77,13 @@
77
77
  "integration.canvas.node.badge.loopBody": "Loop — nothing is wired to Item yet, so nothing repeats | Loop — repeats the one step wired to Item, once per element | Loop — repeats the {n} steps wired to Item, once per element",
78
78
  "integration.canvas.node.badge.noBuiltCode": "Version {version} is not ready to use — this step cannot be tested",
79
79
  "integration.canvas.node.badge.repeats": "Repeats — runs once per element of {iterators} | Repeats — runs once per element of each of the {n} loops it sits inside: {iterators}",
80
+ "integration.canvas.node.handle.converging": "Converging input: the branch that arrives is handed on as the input",
81
+ "integration.canvas.node.handle.convergingKeyed": "Branches of one split arrive together, each under the step it ends in",
80
82
  "integration.canvas.node.handle.input": "Input",
83
+ "integration.canvas.node.handle.merger": "Merger: waits for every branch and hands each one on under the step it ends in",
84
+ "integration.canvas.node.handle.splitter": "Splitter: all branches run",
85
+ "integration.canvas.node.handle.virtualConverging": "Converging input, drawn only: whichever of these branches arrives",
86
+ "integration.canvas.node.handle.virtualMerger": "Merger, drawn only: waits for every branch",
81
87
  "integration.canvas.node.meta.versionTitle": "Version {version}",
82
88
  "integration.canvas.node.note.heading": "Note",
83
89
  "integration.canvas.node.port.outputFallback": "out",
@@ -385,6 +391,14 @@
385
391
  "integration.editor.clipboard.error.read": "Could not read the clipboard",
386
392
  "integration.editor.clipboard.error.write": "Could not write to the clipboard",
387
393
  "integration.editor.clipboard.toast.copied": "Node copied | {n} nodes copied",
394
+ "integration.editor.connection.refused.copied": "{n} connection between the copies was left out because it would cross a loop's boundary. | {n} connections between the copies were left out because they would cross a loop's boundary.",
395
+ "integration.editor.connection.refused.copiedTitle": "Copied without some connections",
396
+ "integration.editor.connection.refused.cycle": "{source} already runs after {target}, so this connection would close a cycle.",
397
+ "integration.editor.connection.refused.cycleUnnamed": "This would close a cycle: a step would run after itself.",
398
+ "integration.editor.connection.refused.loopBoundary": "{inside} is inside the loop {loop}; only its Item output may lead into the loop's steps.",
399
+ "integration.editor.connection.refused.loopBoundaryItem": "{outside} is reached from outside the loop {loop} too, so the loop's Item output cannot lead to it.",
400
+ "integration.editor.connection.refused.loopBoundaryOut": "{inside} is inside the loop {loop}, and {outside} is reached from outside it too; only its Done output may lead out of the loop.",
401
+ "integration.editor.connection.refused.title": "Connection not possible",
388
402
  "integration.editor.deactivate.dialog.cancel": "Cancel",
389
403
  "integration.editor.deactivate.dialog.confirm": "Save as paused",
390
404
  "integration.editor.deactivate.dialog.description.paused": "paused",
@@ -581,14 +595,23 @@
581
595
  "integration.nodeConfig.expression.picker.filterPlaceholder": "Filter…",
582
596
  "integration.nodeConfig.expression.pill.inputPath": "Input · {rest}",
583
597
  "integration.nodeConfig.expression.pill.inputPayload": "Input payload",
598
+ "integration.nodeConfig.expression.pill.runId": "Run ID",
599
+ "integration.nodeConfig.expression.pill.runUrl": "Run link",
584
600
  "integration.nodeConfig.expression.pill.triggerPath": "Trigger · {rest}",
585
601
  "integration.nodeConfig.expression.pill.triggerPayload": "Trigger payload",
586
602
  "integration.nodeConfig.expression.pill.variable": "Variable · {path}",
603
+ "integration.nodeConfig.expression.pill.workflowId": "Workflow ID",
604
+ "integration.nodeConfig.expression.pill.workflowName": "Workflow name",
587
605
  "integration.nodeConfig.expression.preview.missTitle": "Parts of this expression have no sample data yet",
588
606
  "integration.nodeConfig.expression.suggestion.heading.input": "INPUT",
589
607
  "integration.nodeConfig.expression.suggestion.heading.nodeOutputs": "NODE OUTPUTS",
608
+ "integration.nodeConfig.expression.suggestion.heading.run": "RUN",
590
609
  "integration.nodeConfig.expression.suggestion.heading.variables": "VARIABLES",
591
610
  "integration.nodeConfig.expression.suggestion.inputPayload": "input payload",
611
+ "integration.nodeConfig.expression.suggestion.runId": "run ID",
612
+ "integration.nodeConfig.expression.suggestion.runUrl": "run link",
613
+ "integration.nodeConfig.expression.suggestion.workflowId": "workflow ID",
614
+ "integration.nodeConfig.expression.suggestion.workflowName": "workflow name",
592
615
  "integration.nodeConfig.expression.toggle.off": "Back to the regular control (clears the expression)",
593
616
  "integration.nodeConfig.expression.toggle.on": "Map this value from a previous step instead",
594
617
  "integration.nodeConfig.expression.useFit": "Use:",
@@ -990,10 +1013,14 @@
990
1013
  "integration.runs.response.title.starting": "Starting run",
991
1014
  "integration.runs.response.title.sync": "Run response",
992
1015
  "integration.runs.response.title.unconfirmed": "Start not confirmed",
1016
+ "integration.runs.skip.deadEnd": "Skipped: dead end",
1017
+ "integration.runs.skip.deadEndBranch": "Skipped: dead end in branch {branch}",
1018
+ "integration.runs.skip.plain": "Skipped",
993
1019
  "integration.runs.status.cancelled": "cancelled",
994
1020
  "integration.runs.status.failed": "failed",
995
1021
  "integration.runs.status.queued": "queued",
996
1022
  "integration.runs.status.running": "running",
1023
+ "integration.runs.status.skipped": "skipped",
997
1024
  "integration.runs.status.succeeded": "succeeded",
998
1025
  "integration.runs.table.column.duration": "Duration",
999
1026
  "integration.runs.table.column.id": "ID",
@@ -1393,5 +1420,13 @@
1393
1420
  "integration.nodeVersions.badge.offered": "Offered",
1394
1421
  "integration.nodeVersions.badge.notBuilt": "Not built",
1395
1422
  "integration.nodeVersions.action.retire": "Retire",
1396
- "integration.nodeVersions.action.restore": "Restore"
1423
+ "integration.nodeVersions.action.restore": "Restore",
1424
+ "integration.editor.connection.joinRule.title": "This will not save",
1425
+ "integration.editor.connection.joinRule.crossing": "The connection from node “{from}” (output {output}) to node “{to}” joins two paths that must run separately. Delete this connection or lead it to a node on the same path.",
1426
+ "integration.editor.connection.joinRule.mergerAcrossSplitters": "Paths that split at different places come together in node “{step}”. First bring the paths of each split together in a node of their own.",
1427
+ "integration.editor.connection.joinRule.splitterBypassed": "Paths that split earlier lead to node “{step}” – and one connection also goes around that split. Delete this extra connection.",
1428
+ "integration.editor.connection.joinRule.undecomposable": "Paths that always run and paths that run only under a certain condition come together in node “{step}”. Bring these paths together in separate nodes.",
1429
+ "integration.editor.unsavable.dialog.back": "Back to the editor",
1430
+ "integration.editor.unsavable.dialog.description": "This workflow is currently invalid. It can’t be saved like this. Please fix these errors first:",
1431
+ "integration.editor.unsavable.dialog.title": "Can’t save this workflow"
1397
1432
  }
@@ -140,7 +140,7 @@ const columns = computed(() => [
140
140
  <Clock :size="14" />
141
141
  </div>
142
142
  <div class="min-w-0">
143
- <div class="font-medium text-sm truncate">{{ e.workflowName }}</div>
143
+ <div class="font-medium text-sm truncate" :title="e.workflowName">{{ e.workflowName }}</div>
144
144
  </div>
145
145
  </div>
146
146
  </template>
@@ -45,6 +45,7 @@ import { isTerminalRun, unwrapRun } from "../../../utils/runEnvelope";
45
45
  import { findingsSummary, groupFindingsByNode, nodeDisplayLabel } from "../../../utils/validationFindings";
46
46
  import { payloadFieldsFromBlob } from "../../../data/payloadForm";
47
47
  import { eventTopicOf } from "../../../data/eventTrigger";
48
+ import { isShapeIssue, saveRefusalLines } from "../../../data/saveRefusal";
48
49
  import WorkflowIconView from "../../../components/Integrations/WorkflowIconView.vue";
49
50
  import { DEFAULT_RUN_DIRECTION, DEFAULT_RUN_SORT } from "../../../utils/runFeedQuery";
50
51
  import { keepOpenBeside } from "../../../utils/dialog";
@@ -114,6 +115,12 @@ onMounted(() => {
114
115
  });
115
116
  const deactivationOpen = ref(false);
116
117
  const deactivationIssues = ref([]);
118
+ const unsavableOpen = ref(false);
119
+ const unsavableLines = ref([]);
120
+ function showUnsavable(issues, blob) {
121
+ unsavableLines.value = saveRefusalLines(issues, blob.nodes, blob.edges, blob.triggers);
122
+ unsavableOpen.value = true;
123
+ }
117
124
  const { load: loadCredentials, needsReauth } = useIntegrationsCredentials();
118
125
  onMounted(() => {
119
126
  void loadCredentials();
@@ -795,7 +802,9 @@ async function save() {
795
802
  settleBuildStatus();
796
803
  } catch (e) {
797
804
  const issues = apiValidationIssues(e);
798
- if (issues.length && workflow.value.active) {
805
+ if (issues.some((i) => isShapeIssue(i.path))) {
806
+ showUnsavable(issues, payloadBlob(d));
807
+ } else if (issues.length && workflow.value.active) {
799
808
  const nodes = workflow.value.blob.nodes;
800
809
  deactivationIssues.value = issues.map((i) => {
801
810
  const m = /^blob\.nodes\.(\d+)\b/.exec(i.path);
@@ -832,7 +841,9 @@ async function confirmDeactivate() {
832
841
  settleBuildStatus();
833
842
  } catch (e) {
834
843
  deactivationOpen.value = false;
835
- saveError.value = errorReason(e, t("integration.editor.save.error.generic"));
844
+ const issues = apiValidationIssues(e);
845
+ if (issues.length) showUnsavable(issues, payloadBlob(d));
846
+ else saveError.value = errorReason(e, t("integration.editor.save.error.generic"));
836
847
  } finally {
837
848
  saving.value = false;
838
849
  }
@@ -1139,7 +1150,7 @@ async function confirmDeactivate() {
1139
1150
  :draft="draft?.blob ?? null"
1140
1151
  :run-busy="saving || running || syncLoading || waitingForBuild"
1141
1152
  :run-saves="isDirty"
1142
- :overlay-open="settingsOpen || duplicateOpen || importOpen || !!exporter?.open || deleteOpen || syncOpen || runPayloadOpen || deactivationOpen || leaveOpen"
1153
+ :overlay-open="settingsOpen || duplicateOpen || importOpen || !!exporter?.open || deleteOpen || syncOpen || runPayloadOpen || deactivationOpen || unsavableOpen || leaveOpen"
1143
1154
  @change="onChange"
1144
1155
  @run="runFromEditor"
1145
1156
  @toggle-active="onToggleActive"
@@ -1433,5 +1444,29 @@ async function confirmDeactivate() {
1433
1444
  </AlertDialogFooter>
1434
1445
  </AlertDialogContent>
1435
1446
  </AlertDialog>
1447
+
1448
+ <!-- A save refused whatever `active` says: nothing to offer but going back. -->
1449
+ <AlertDialog :open="unsavableOpen" @update:open="(v) => {
1450
+ if (!v) unsavableOpen = false;
1451
+ }">
1452
+ <AlertDialogContent>
1453
+ <AlertDialogHeader>
1454
+ <AlertDialogTitle>{{ t("integration.editor.unsavable.dialog.title") }}</AlertDialogTitle>
1455
+ <AlertDialogDescription>{{ t("integration.editor.unsavable.dialog.description") }}</AlertDialogDescription>
1456
+ </AlertDialogHeader>
1457
+ <ul class="max-h-48 space-y-0.5 overflow-y-auto rounded-md border border-red-500/20 bg-red-500/5 px-3 py-2 text-sm text-red-800">
1458
+ <li v-for="(line, i) in unsavableLines" :key="i" class="flex gap-1.5">
1459
+ <span class="select-none text-red-500">•</span>
1460
+ <span v-if="'key' in line">{{ t(line.key, line.params) }}</span>
1461
+ <span v-else><span v-if="line.where" class="font-medium">{{ line.where }}:</span> {{ line.message }}</span>
1462
+ </li>
1463
+ </ul>
1464
+ <AlertDialogFooter>
1465
+ <Button variant="outline" @click="unsavableOpen = false">
1466
+ {{ t("integration.editor.unsavable.dialog.back") }}
1467
+ </Button>
1468
+ </AlertDialogFooter>
1469
+ </AlertDialogContent>
1470
+ </AlertDialog>
1436
1471
  </IntegrationsLayout>
1437
1472
  </template>
@@ -696,11 +696,20 @@ export interface WorkflowRunNodeStep {
696
696
  export interface RunStepRow {
697
697
  node_id: string;
698
698
  node_slug: string;
699
- activity_type: string;
699
+ activity_type?: string | null;
700
700
  status: string;
701
- attempt: number;
702
- scheduled_event_id: number | null;
703
- duration_ms: number | null;
701
+ attempt?: number | null;
702
+ scheduled_event_id?: number | null;
703
+ duration_ms?: number | null;
704
+ /** Why a `skipped` step was skipped. Open-ended: unknown values are legal. */
705
+ skip_reason?: string | null;
706
+ /** `dead_end` only: the 1-based number of the splitter's branch that delivered nothing, in connection order. */
707
+ dead_end_branch?: number | null;
708
+ /** `dead_end` only: the splitter (node and output port) whose branch was a dead end. */
709
+ dead_end_splitter?: {
710
+ node_id: string;
711
+ port: string;
712
+ } | null;
704
713
  branch?: string | null;
705
714
  error?: string | null;
706
715
  input?: unknown;
@@ -23,11 +23,14 @@ export function apiRefusal(err, drawn) {
23
23
  if (!(err instanceof IntegrationsApiError) || err.status !== 422) return refusal;
24
24
  const errors = err.body?.errors;
25
25
  if (!errors || typeof errors !== "object") return refusal;
26
- const keys = Object.keys(errors).filter((key) => key !== "blob" && !key.startsWith("blob."));
27
- for (const key of keys) {
28
- if (keys.some((other) => other.startsWith(`${key}.`))) continue;
29
- const messages = (Array.isArray(errors[key]) ? errors[key] : [errors[key]]).filter((message) => message !== void 0 && message !== null).map(String);
26
+ const entries = Object.entries(errors).filter(([key]) => key !== "blob" && !key.startsWith("blob.")).map(([key, val]) => ({
27
+ key,
28
+ messages: (Array.isArray(val) ? val : [val]).filter((message) => message !== void 0 && message !== null).map(String)
29
+ }));
30
+ for (const { key, messages } of entries) {
30
31
  if (!messages.length) continue;
32
+ const isContainerOnly = !drawn.includes(key);
33
+ if (isContainerOnly && entries.some((other) => other.key.startsWith(`${key}.`) && other.messages.length)) continue;
31
34
  if (drawn.includes(key)) refusal.atFields[key] = messages[0];
32
35
  else refusal.unshown.push(...messages.map((message) => ({ key, message })));
33
36
  }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * What a node package is called where a person reads it: the label the package
3
+ * declares, or — for a version published before packages carried one — its npm
4
+ * name without scope and `integrations-nodes-` prefix, title-cased.
5
+ *
6
+ * One function because three surfaces name packages: the palette's folder for
7
+ * an app package, the template gallery's badge for the integration a template
8
+ * ships with, and the canvas card's line for the package a node comes from. They
9
+ * must not disagree on what a package is called. An empty label counts as none,
10
+ * as it always has in the palette.
11
+ */
12
+ export declare function packageLabel(pkg: {
13
+ name: string;
14
+ label?: string | null;
15
+ }): string;
16
+ /** The npm name without scope and `integrations-nodes-` prefix: `erpnext`, `core`. */
17
+ export declare function packageTail(name: string): string;
@@ -0,0 +1,6 @@
1
+ export function packageLabel(pkg) {
2
+ return pkg.label || packageTail(pkg.name).split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" ");
3
+ }
4
+ export function packageTail(name) {
5
+ return (name.split("/").pop() ?? name).replace(/^integrations-nodes-/, "");
6
+ }
@@ -0,0 +1,39 @@
1
+ import type { RunStepRow } from '../types/integrations.js';
2
+ /**
3
+ * Why a run step was skipped (PO-750, from the worker's PO-502).
4
+ *
5
+ * A step the run never reached because a branch delivered nothing is reported as
6
+ * a synthetic row: `status: 'skipped'`, `skip_reason: 'dead_end'`, and the number
7
+ * of the splitter's branch that was the dead end. The reason list is open — the
8
+ * worker may name more later — so anything but `dead_end` reads as a plain skip
9
+ * rather than being shown raw or hidden.
10
+ */
11
+ export type SkipReason = {
12
+ kind: 'dead_end';
13
+ branch: number | null;
14
+ } | {
15
+ kind: 'plain';
16
+ };
17
+ type StepLike = Pick<RunStepRow, 'status' | 'skip_reason' | 'dead_end_branch'>;
18
+ /** A step that never ran. Case-insensitive, like the rest of the status vocabulary. */
19
+ export declare function isSkippedStep(step: Pick<RunStepRow, 'status'>): boolean;
20
+ /** The reason a step was skipped, or null for a step that ran. */
21
+ export declare function skipReason(step: StepLike): SkipReason | null;
22
+ /**
23
+ * The message key and parameters that say why a step was skipped, or null for a
24
+ * step that ran or was skipped for a reason this studio does not name (the status
25
+ * badge already says "skipped" then).
26
+ */
27
+ export declare function skipReasonMessage(step: StepLike): {
28
+ key: string;
29
+ params: Record<string, number>;
30
+ } | null;
31
+ /** Nodes a run actually executed — a skipped step is on the list but did not run. */
32
+ export declare function executedNodeIds(steps: ReadonlyArray<Pick<RunStepRow, 'node_id' | 'status'>>): Set<string>;
33
+ /**
34
+ * A step's status as its badge says it. A skipped step is a step's state, not a
35
+ * run's, so it is not among the run words `runStatusLabel` translates — and without
36
+ * this the badge printed the raw `SKIPPED` in a German studio (review of #297).
37
+ */
38
+ export declare function stepStatusLabel(status: string | null | undefined): string;
39
+ export {};
@@ -0,0 +1,22 @@
1
+ import { useIntegrationsT } from "../composables/useIntegrationsT.js";
2
+ import { runStatusLabel } from "./statusStyle.js";
3
+ export function isSkippedStep(step) {
4
+ return String(step.status ?? "").toLowerCase() === "skipped";
5
+ }
6
+ export function skipReason(step) {
7
+ if (!isSkippedStep(step)) return null;
8
+ if (step.skip_reason !== "dead_end") return { kind: "plain" };
9
+ const n = step.dead_end_branch;
10
+ return { kind: "dead_end", branch: typeof n === "number" && Number.isInteger(n) && n >= 1 ? n : null };
11
+ }
12
+ export function skipReasonMessage(step) {
13
+ const reason = skipReason(step);
14
+ if (reason?.kind !== "dead_end") return null;
15
+ return reason.branch === null ? { key: "integration.runs.skip.deadEnd", params: {} } : { key: "integration.runs.skip.deadEndBranch", params: { branch: reason.branch } };
16
+ }
17
+ export function executedNodeIds(steps) {
18
+ return new Set(steps.filter((s) => !isSkippedStep(s)).map((s) => s.node_id));
19
+ }
20
+ export function stepStatusLabel(status) {
21
+ return isSkippedStep({ status: status ?? "" }) ? useIntegrationsT()("integration.runs.status.skipped") : runStatusLabel(status);
22
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@revenexx/studio-integrations",
3
- "version": "2.8.1",
3
+ "version": "2.10.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": {
@@ -56,8 +56,8 @@
56
56
  "@changesets/cli": "^3.0.3",
57
57
  "@nuxt/eslint-config": "^1.17.0",
58
58
  "@nuxt/kit": "^4.0.0",
59
- "@nuxt/module-builder": "^1.0.2",
60
- "@nuxt/schema": "^4.0.0",
59
+ "@nuxt/module-builder": "^1.0.3",
60
+ "@nuxt/schema": "^4.5.2",
61
61
  "@playwright/test": "^1.57.0",
62
62
  "@revenexx/talkback-js": "^0.3.0",
63
63
  "eslint": "^10.11.0",
@@ -1,21 +0,0 @@
1
- /**
2
- * @deprecated Use `NodeMark` directly. This is a thin back-compat shim kept so
3
- * that hosts still referencing the auto-registered `<IntegrationsNodeLogo>`
4
- * (e.g. integrations/studio-ui `local-nodes.vue`) keep resolving the component
5
- * after PO-194 renamed NodeLogo → NodeMark. Auto-registered components are
6
- * public API surface for the hosts, so a silent delete breaks them at a
7
- * different repo's build, invisible to this repo's CI.
8
- *
9
- * The old NodeLogo rendered "logo OR glyph, logo preferred" — exactly
10
- * `NodeMark`'s `logo-only` behaviour (logo when present, glyph fallback). Drop
11
- * this shim one release after the hosts have migrated to `NodeMark`.
12
- */
13
- import type { NodeManifest } from '../../types/integrations.js';
14
- type __VLS_Props = {
15
- manifest: NodeManifest | null;
16
- size?: number;
17
- };
18
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
19
- size: number;
20
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
- export default _default;
@@ -1,10 +0,0 @@
1
- <script setup>
2
- defineProps({
3
- manifest: { type: [Object, null], required: true },
4
- size: { type: Number, required: false, default: 16 }
5
- });
6
- </script>
7
-
8
- <template>
9
- <IntegrationsNodeMark :manifest="manifest" :size="size" logo-only />
10
- </template>
@@ -1,21 +0,0 @@
1
- /**
2
- * @deprecated Use `NodeMark` directly. This is a thin back-compat shim kept so
3
- * that hosts still referencing the auto-registered `<IntegrationsNodeLogo>`
4
- * (e.g. integrations/studio-ui `local-nodes.vue`) keep resolving the component
5
- * after PO-194 renamed NodeLogo → NodeMark. Auto-registered components are
6
- * public API surface for the hosts, so a silent delete breaks them at a
7
- * different repo's build, invisible to this repo's CI.
8
- *
9
- * The old NodeLogo rendered "logo OR glyph, logo preferred" — exactly
10
- * `NodeMark`'s `logo-only` behaviour (logo when present, glyph fallback). Drop
11
- * this shim one release after the hosts have migrated to `NodeMark`.
12
- */
13
- import type { NodeManifest } from '../../types/integrations.js';
14
- type __VLS_Props = {
15
- manifest: NodeManifest | null;
16
- size?: number;
17
- };
18
- declare const _default: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
19
- size: number;
20
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
21
- export default _default;