@walkeros/cli 2.2.0-next-1773136823705 → 3.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.
package/dist/index.js CHANGED
@@ -573,6 +573,8 @@ var init_core = __esm({
573
573
  init_local_packages();
574
574
  init_input_detector();
575
575
  init_stdin();
576
+ init_auth();
577
+ init_sse();
576
578
  }
577
579
  });
578
580
 
@@ -744,6 +746,7 @@ var init_config = __esm({
744
746
  "src/config/index.ts"() {
745
747
  "use strict";
746
748
  init_validators();
749
+ init_build_defaults();
747
750
  init_utils();
748
751
  init_loader();
749
752
  }
@@ -751,8 +754,10 @@ var init_config = __esm({
751
754
 
752
755
  // src/core/cache-utils.ts
753
756
  import { getHashServer } from "@walkeros/server-core";
757
+ import semver from "semver";
754
758
  function isMutableVersion(version) {
755
- return version === "latest" || version.includes("^") || version.includes("~") || version.includes("*") || version.includes("x");
759
+ if (semver.valid(version)) return false;
760
+ return true;
756
761
  }
757
762
  function getTodayDate() {
758
763
  return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
@@ -789,7 +794,7 @@ var init_cache_utils = __esm({
789
794
  import pacote from "pacote";
790
795
  import path7 from "path";
791
796
  import fs6 from "fs-extra";
792
- import semver from "semver";
797
+ import semver2 from "semver";
793
798
  async function withTimeout(promise, ms, errorMessage) {
794
799
  let timer;
795
800
  const timeout = new Promise((_2, reject) => {
@@ -901,14 +906,14 @@ function resolveVersionConflicts(allSpecs, logger) {
901
906
  (a2, b2) => SOURCE_PRIORITY[a2.source] - SOURCE_PRIORITY[b2.source]
902
907
  );
903
908
  const directSpecs = activeSpecs.filter((s2) => s2.source === "direct");
904
- const directExact = directSpecs.find((s2) => semver.valid(s2.spec) !== null);
909
+ const directExact = directSpecs.find((s2) => semver2.valid(s2.spec) !== null);
905
910
  let chosenVersion;
906
911
  if (directExact) {
907
912
  chosenVersion = directExact.spec;
908
913
  } else if (directSpecs.length > 0) {
909
914
  chosenVersion = directSpecs[0].spec;
910
915
  } else {
911
- const exactVersions = activeSpecs.filter((s2) => semver.valid(s2.spec) !== null).map((s2) => s2.spec);
916
+ const exactVersions = activeSpecs.filter((s2) => semver2.valid(s2.spec) !== null).map((s2) => s2.spec);
912
917
  const uniqueExact = [...new Set(exactVersions)];
913
918
  if (uniqueExact.length > 1) {
914
919
  throw new Error(
@@ -920,10 +925,10 @@ function resolveVersionConflicts(allSpecs, logger) {
920
925
  chosenVersion = activeSpecs[0].spec;
921
926
  }
922
927
  }
923
- if (semver.valid(chosenVersion)) {
928
+ if (semver2.valid(chosenVersion)) {
924
929
  for (const spec of specs) {
925
930
  if (spec.localPath) continue;
926
- if (semver.valid(spec.spec)) {
931
+ if (semver2.valid(spec.spec)) {
927
932
  if (spec.spec !== chosenVersion) {
928
933
  if (spec.source === "peerDependency") {
929
934
  logger.warn(
@@ -932,7 +937,7 @@ function resolveVersionConflicts(allSpecs, logger) {
932
937
  }
933
938
  }
934
939
  } else {
935
- if (!semver.satisfies(chosenVersion, spec.spec, {
940
+ if (!semver2.satisfies(chosenVersion, spec.spec, {
936
941
  includePrerelease: true
937
942
  })) {
938
943
  if (spec.source === "peerDependency") {
@@ -2506,11 +2511,11 @@ import fs12 from "fs-extra";
2506
2511
  import { assign as o } from "@walkeros/core";
2507
2512
  import { assign as r, createLogger as i } from "@walkeros/core";
2508
2513
  import { assign as a, clone as c, debounce as u, getId as f, getGrantedConsent as l, isDefined as g, isFunction as d, isObject as m, processEventMapping as p, tryCatchAsync as h, useHooks as w } from "@walkeros/core";
2509
- import { isArray as y } from "@walkeros/core";
2510
- import { tryCatch as b, tryCatchAsync as v } from "@walkeros/core";
2511
- import { getMappingValue as k, tryCatchAsync as C } from "@walkeros/core";
2512
- import { isObject as O, tryCatchAsync as j, useHooks as q } from "@walkeros/core";
2513
- import { assign as M, getId as Q, isFunction as V, isString as _ } from "@walkeros/core";
2514
+ import { isArray as b } from "@walkeros/core";
2515
+ import { tryCatch as y, tryCatchAsync as v } from "@walkeros/core";
2516
+ import { getMappingValue as k, tryCatchAsync as O } from "@walkeros/core";
2517
+ import { isObject as C, tryCatchAsync as j, useHooks as q } from "@walkeros/core";
2518
+ import { assign as L, getId as Q, isFunction as V, isString as _ } from "@walkeros/core";
2514
2519
  import { isObject as K } from "@walkeros/core";
2515
2520
  import { getGrantedConsent as en, processEventMapping as tn, tryCatchAsync as on, useHooks as sn } from "@walkeros/core";
2516
2521
  import { useHooks as an, tryCatchAsync as cn } from "@walkeros/core";
@@ -2555,7 +2560,7 @@ async function x(n, e2, t2) {
2555
2560
  s2.debug("init");
2556
2561
  const i2 = await q(e2.init, "TransformerInit", n.hooks)(r2);
2557
2562
  if (false === i2) return false;
2558
- e2.config = { ...i2 || e2.config, init: true }, s2.debug("init done");
2563
+ e2.config = { ...i2 || e2.config, env: i2?.env || e2.config.env, init: true }, s2.debug("init done");
2559
2564
  }
2560
2565
  return true;
2561
2566
  }
@@ -2588,7 +2593,7 @@ async function S(n, e2, t2, o2, s2, r2) {
2588
2593
  return i2;
2589
2594
  }
2590
2595
  function $(n) {
2591
- return n && O(n) ? n : {};
2596
+ return n && C(n) ? n : {};
2592
2597
  }
2593
2598
  async function R(n, e2, t2) {
2594
2599
  const { code: o2, config: s2 = {}, env: r2 = {}, primary: i2, next: a2 } = t2;
@@ -2597,7 +2602,7 @@ async function R(n, e2, t2) {
2597
2602
  c2 = s2.ingest ? await k(e3, s2.ingest, { collector: n }) : void 0;
2598
2603
  }, setRespond: (n2) => {
2599
2604
  u2 = n2;
2600
- } }, m2 = await C(o2)(d2);
2605
+ } }, m2 = await O(o2)(d2);
2601
2606
  if (!m2) return;
2602
2607
  const p2 = m2.type || "unknown", h2 = n.logger.scope(p2).scope(e2);
2603
2608
  return g2.logger = h2, i2 && (m2.config = { ...m2.config, primary: i2 }), m2;
@@ -2616,15 +2621,15 @@ async function T(n, e2 = {}) {
2616
2621
  return t2;
2617
2622
  }
2618
2623
  async function I(n, e2, t2) {
2619
- const o2 = n.on, s2 = o2[e2] || [], r2 = y(t2) ? t2 : [t2];
2624
+ const o2 = n.on, s2 = o2[e2] || [], r2 = b(t2) ? t2 : [t2];
2620
2625
  r2.forEach((n2) => {
2621
2626
  s2.push(n2);
2622
2627
  }), o2[e2] = s2, await G(n, e2, r2);
2623
2628
  }
2624
2629
  function B(n, e2, t2, o2, s2) {
2625
2630
  if (!e2.on) return;
2626
- const r2 = e2.type || "unknown", i2 = n.logger.scope(r2).scope("on").scope(o2), a2 = { collector: n, logger: i2, id: t2, config: e2.config, data: s2, env: L(e2.env, e2.config.env) };
2627
- b(e2.on)(o2, a2);
2631
+ const r2 = e2.type || "unknown", i2 = n.logger.scope(r2).scope("on").scope(o2), a2 = { collector: n, logger: i2, id: t2, config: e2.config, data: s2, env: W(e2.env, e2.config.env) };
2632
+ y(e2.on)(o2, a2);
2628
2633
  }
2629
2634
  async function G(n, e2, o2, s2) {
2630
2635
  let r2, i2 = o2 || [];
@@ -2681,7 +2686,7 @@ async function G(n, e2, o2, s2) {
2681
2686
  if (-1 === r3) continue;
2682
2687
  if (s3.splice(r3, 1), s3.length > 0) continue;
2683
2688
  delete n2.pending.destinations[t2];
2684
- const i3 = W(o3);
2689
+ const i3 = M(o3);
2685
2690
  false !== i3.config.queue && (i3.queuePush = [...n2.queue]), n2.destinations[t2] = i3;
2686
2691
  }
2687
2692
  })(n, e2), !i2.length) return !a2;
@@ -2691,7 +2696,7 @@ async function G(n, e2, o2, s2) {
2691
2696
  const o3 = t2 || n2.consent;
2692
2697
  e3.forEach((e4) => {
2693
2698
  Object.keys(o3).filter((n3) => n3 in e4).forEach((t3) => {
2694
- b(e4[t3])(n2, o3);
2699
+ y(e4[t3])(n2, o3);
2695
2700
  });
2696
2701
  });
2697
2702
  })(n, i2, s2);
@@ -2700,7 +2705,7 @@ async function G(n, e2, o2, s2) {
2700
2705
  case t.Commands.Run:
2701
2706
  !(function(n2, e3) {
2702
2707
  n2.allowed && e3.forEach((e4) => {
2703
- b(e4)(n2);
2708
+ y(e4)(n2);
2704
2709
  });
2705
2710
  })(n, i2);
2706
2711
  break;
@@ -2708,21 +2713,21 @@ async function G(n, e2, o2, s2) {
2708
2713
  !(function(n2, e3) {
2709
2714
  if (!n2.session) return;
2710
2715
  e3.forEach((e4) => {
2711
- b(e4)(n2, n2.session);
2716
+ y(e4)(n2, n2.session);
2712
2717
  });
2713
2718
  })(n, i2);
2714
2719
  break;
2715
2720
  default:
2716
2721
  i2.forEach((e3) => {
2717
- "function" == typeof e3 && b(e3)(n, r2);
2722
+ "function" == typeof e3 && y(e3)(n, r2);
2718
2723
  });
2719
2724
  }
2720
2725
  return !a2;
2721
2726
  }
2722
2727
  async function H(n, e2, t2) {
2723
2728
  const { code: o2, config: s2 = {}, env: r2 = {}, before: i2 } = e2;
2724
- if (!d(o2.push)) return N({ ok: false, failed: { invalid: { type: "invalid", error: "Destination code must have a push method" } } });
2725
- const a2 = t2 || s2 || { init: false }, c2 = i2 ? { ...a2, before: i2 } : a2, u2 = { ...o2, config: c2, env: L(o2.env, r2) };
2729
+ if (!d(o2.push)) return J({ ok: false, failed: { invalid: { type: "invalid", error: "Destination code must have a push method" } } });
2730
+ const a2 = t2 || s2 || { init: false }, c2 = i2 ? { ...a2, before: i2 } : a2, u2 = { ...o2, config: c2, env: W(o2.env, r2) };
2726
2731
  let l2 = u2.config.id;
2727
2732
  if (!l2) do {
2728
2733
  l2 = f(4);
@@ -2731,7 +2736,7 @@ async function H(n, e2, t2) {
2731
2736
  }
2732
2737
  async function U(n, e2, t2 = {}, o2) {
2733
2738
  const { allowed: s2, consent: r2, globals: i2, user: u2 } = n;
2734
- if (!s2) return N({ ok: false });
2739
+ if (!s2) return J({ ok: false });
2735
2740
  e2 && (n.queue.push(e2), n.status.in++), o2 || (o2 = n.destinations);
2736
2741
  const f2 = await Promise.all(Object.entries(o2 || {}).map(async ([o3, s3]) => {
2737
2742
  let f3 = (s3.queuePush || []).map((n2) => ({ ...n2, consent: r2 }));
@@ -2741,7 +2746,7 @@ async function U(n, e2, t2 = {}, o2) {
2741
2746
  }
2742
2747
  if (!f3.length && !s3.queueOn?.length) return { id: o3, destination: s3, skipped: true };
2743
2748
  if (!f3.length && s3.queueOn?.length) {
2744
- const e3 = await h(F)(n, s3, o3);
2749
+ const e3 = await h(z)(n, s3, o3);
2745
2750
  return { id: o3, destination: s3, skipped: !e3 };
2746
2751
  }
2747
2752
  const g3 = [], d3 = f3.filter((n2) => {
@@ -2749,14 +2754,14 @@ async function U(n, e2, t2 = {}, o2) {
2749
2754
  return !e3 || (n2.consent = e3, g3.push(n2), false);
2750
2755
  });
2751
2756
  if (s3.queuePush.push(...d3), !g3.length) return { id: o3, destination: s3, queue: f3 };
2752
- if (!await h(F)(n, s3, o3)) return { id: o3, destination: s3, queue: f3 };
2757
+ if (!await h(z)(n, s3, o3)) return { id: o3, destination: s3, queue: f3 };
2753
2758
  let m3, p2;
2754
2759
  s3.dlq || (s3.dlq = []);
2755
2760
  const w2 = (function(n2, e3) {
2756
2761
  const t3 = n2.config.before;
2757
2762
  return t3 ? E(t3, D(e3)) : [];
2758
2763
  })(s3, n.transformers);
2759
- let y2 = 0;
2764
+ let b2 = 0;
2760
2765
  return await Promise.all(g3.map(async (e3) => {
2761
2766
  e3.globals = a(i2, e3.globals), e3.user = a(u2, e3.user);
2762
2767
  let r3 = e3;
@@ -2765,12 +2770,12 @@ async function U(n, e2, t2 = {}, o2) {
2765
2770
  if (null === o4) return e3;
2766
2771
  r3 = o4;
2767
2772
  }
2768
- const c2 = Date.now(), f4 = await h(J, (e4) => {
2773
+ const c2 = Date.now(), f4 = await h(F, (e4) => {
2769
2774
  const t3 = s3.type || "unknown";
2770
2775
  n.logger.scope(t3).error("Push failed", { error: e4, event: r3.name }), m3 = e4, s3.dlq.push([r3, e4]);
2771
2776
  })(n, s3, o3, r3, t2.ingest, t2.respond);
2772
- return y2 += Date.now() - c2, void 0 !== f4 && (p2 = f4), e3;
2773
- })), { id: o3, destination: s3, error: m3, response: p2, totalDuration: y2 };
2777
+ return b2 += Date.now() - c2, void 0 !== f4 && (p2 = f4), e3;
2778
+ })), { id: o3, destination: s3, error: m3, response: p2, totalDuration: b2 };
2774
2779
  })), g2 = {}, d2 = {}, m2 = {};
2775
2780
  for (const e3 of f2) {
2776
2781
  if (e3.skipped) continue;
@@ -2779,11 +2784,11 @@ async function U(n, e2, t2 = {}, o2) {
2779
2784
  const o3 = n.status.destinations[e3.id], s3 = Date.now();
2780
2785
  e3.error ? (t3.error = e3.error, m2[e3.id] = t3, o3.failed++, o3.lastAt = s3, o3.duration += e3.totalDuration || 0, n.status.failed++) : e3.queue && e3.queue.length ? d2[e3.id] = t3 : (g2[e3.id] = t3, o3.count++, o3.lastAt = s3, o3.duration += e3.totalDuration || 0, n.status.out++);
2781
2786
  }
2782
- return N({ event: e2, ...Object.keys(g2).length && { done: g2 }, ...Object.keys(d2).length && { queued: d2 }, ...Object.keys(m2).length && { failed: m2 } });
2787
+ return J({ event: e2, ...Object.keys(g2).length && { done: g2 }, ...Object.keys(d2).length && { queued: d2 }, ...Object.keys(m2).length && { failed: m2 } });
2783
2788
  }
2784
- async function F(n, e2, t2) {
2789
+ async function z(n, e2, t2) {
2785
2790
  if (e2.init && !e2.config.init) {
2786
- const o2 = e2.type || "unknown", s2 = n.logger.scope(o2), r2 = { collector: n, logger: s2, id: t2, config: e2.config, env: L(e2.env, e2.config.env) };
2791
+ const o2 = e2.type || "unknown", s2 = n.logger.scope(o2), r2 = { collector: n, logger: s2, id: t2, config: e2.config, env: W(e2.env, e2.config.env) };
2787
2792
  s2.debug("init");
2788
2793
  const i2 = await w(e2.init, "DestinationInit", n.hooks)(r2);
2789
2794
  if (false === i2) return i2;
@@ -2796,10 +2801,10 @@ async function F(n, e2, t2) {
2796
2801
  }
2797
2802
  return true;
2798
2803
  }
2799
- async function J(n, e2, t2, o2, s2, r2) {
2804
+ async function F(n, e2, t2, o2, s2, r2) {
2800
2805
  const { config: i2 } = e2, a2 = await p(o2, i2, n);
2801
2806
  if (a2.ignore) return false;
2802
- const c2 = e2.type || "unknown", f2 = n.logger.scope(c2), l2 = { collector: n, logger: f2, id: t2, config: i2, data: a2.data, rule: a2.mapping, ingest: s2, env: { ...L(e2.env, i2.env), ...r2 ? { respond: r2 } : {} } }, d2 = a2.mapping, m2 = a2.mappingKey || "* *";
2807
+ const c2 = e2.type || "unknown", f2 = n.logger.scope(c2), l2 = { collector: n, logger: f2, id: t2, config: i2, data: a2.data, rule: a2.mapping, ingest: s2, env: { ...W(e2.env, i2.env), ...r2 ? { respond: r2 } : {} } }, d2 = a2.mapping, m2 = a2.mappingKey || "* *";
2803
2808
  if (!d2?.batch || !e2.pushBatch) {
2804
2809
  f2.debug("push", { event: a2.event.name });
2805
2810
  const t3 = await w(e2.push, "DestinationPush", n.hooks)(a2.event, l2);
@@ -2809,7 +2814,7 @@ async function J(n, e2, t2, o2, s2, r2) {
2809
2814
  if (e2.batches = e2.batches || {}, !e2.batches[m2]) {
2810
2815
  const o4 = { key: m2, events: [], data: [] };
2811
2816
  e2.batches[m2] = { batched: o4, batchFn: u(() => {
2812
- const o5 = e2.batches[m2].batched, a3 = { collector: n, logger: f2, id: t2, config: i2, data: void 0, rule: d2, ingest: s2, env: { ...L(e2.env, i2.env), ...r2 ? { respond: r2 } : {} } };
2817
+ const o5 = e2.batches[m2].batched, a3 = { collector: n, logger: f2, id: t2, config: i2, data: void 0, rule: d2, ingest: s2, env: { ...W(e2.env, i2.env), ...r2 ? { respond: r2 } : {} } };
2813
2818
  f2.debug("push batch", { events: o5.events.length }), w(e2.pushBatch, "DestinationPushBatch", n.hooks)(o5, a3), f2.debug("push batch done"), o5.events = [], o5.data = [];
2814
2819
  }, d2.batch) };
2815
2820
  }
@@ -2818,19 +2823,19 @@ async function J(n, e2, t2, o2, s2, r2) {
2818
2823
  }
2819
2824
  return true;
2820
2825
  }
2821
- function N(n) {
2826
+ function J(n) {
2822
2827
  return { ok: !n?.failed, ...n };
2823
2828
  }
2824
- function W(n) {
2825
- const { code: e2, config: t2 = {}, env: o2 = {} } = n, { config: s2 } = A(n, "before"), r2 = { ...e2.config, ...t2, ...s2 }, i2 = L(e2.env, o2);
2829
+ function M(n) {
2830
+ const { code: e2, config: t2 = {}, env: o2 = {} } = n, { config: s2 } = A(n, "before"), r2 = { ...e2.config, ...t2, ...s2 }, i2 = W(e2.env, o2);
2826
2831
  return { ...e2, config: r2, env: i2 };
2827
2832
  }
2828
- async function z(n, e2 = {}) {
2833
+ async function N(n, e2 = {}) {
2829
2834
  const t2 = {};
2830
- for (const [o2, s2] of Object.entries(e2)) s2.config?.require?.length ? n.pending.destinations[o2] = s2 : t2[o2] = W(s2);
2835
+ for (const [o2, s2] of Object.entries(e2)) s2.config?.require?.length ? n.pending.destinations[o2] = s2 : t2[o2] = M(s2);
2831
2836
  return t2;
2832
2837
  }
2833
- function L(n, e2) {
2838
+ function W(n, e2) {
2834
2839
  return n || e2 ? e2 ? n && m(n) && m(e2) ? { ...n, ...e2 } : e2 : n : {};
2835
2840
  }
2836
2841
  async function X(n, e2, t2) {
@@ -2850,7 +2855,7 @@ async function Y(n, e2, o2, r2) {
2850
2855
  let i2, a2, c2 = false, u2 = false;
2851
2856
  switch (e2) {
2852
2857
  case t.Commands.Config:
2853
- K(o2) && (M(n.config, o2, { shallow: false }), a2 = o2, c2 = true);
2858
+ K(o2) && (L(n.config, o2, { shallow: false }), a2 = o2, c2 = true);
2854
2859
  break;
2855
2860
  case t.Commands.Consent:
2856
2861
  if (K(o2)) {
@@ -2859,13 +2864,13 @@ async function Y(n, e2, o2, r2) {
2859
2864
  }
2860
2865
  break;
2861
2866
  case t.Commands.Custom:
2862
- K(o2) && (n.custom = M(n.custom, o2), a2 = o2, c2 = true);
2867
+ K(o2) && (n.custom = L(n.custom, o2), a2 = o2, c2 = true);
2863
2868
  break;
2864
2869
  case t.Commands.Destination:
2865
2870
  K(o2) && ("code" in o2 && K(o2.code) ? i2 = await H(n, o2, r2) : V(o2.push) && (i2 = await H(n, { code: o2 }, r2)));
2866
2871
  break;
2867
2872
  case t.Commands.Globals:
2868
- K(o2) && (n.globals = M(n.globals, o2), a2 = o2, c2 = true);
2873
+ K(o2) && (n.globals = L(n.globals, o2), a2 = o2, c2 = true);
2869
2874
  break;
2870
2875
  case t.Commands.On:
2871
2876
  _(o2) && await I(n, o2, r2);
@@ -2886,20 +2891,20 @@ async function Y(n, e2, o2, r2) {
2886
2891
  })(n);
2887
2892
  break;
2888
2893
  case t.Commands.User:
2889
- K(o2) && (M(n.user, o2, { shallow: false }), a2 = o2, c2 = true);
2894
+ K(o2) && (L(n.user, o2, { shallow: false }), a2 = o2, c2 = true);
2890
2895
  }
2891
- return c2 && await G(n, e2, void 0, a2), u2 && (i2 = await U(n)), i2 || N({ ok: true });
2896
+ return c2 && await G(n, e2, void 0, a2), u2 && (i2 = await U(n)), i2 || J({ ok: true });
2892
2897
  }
2893
2898
  function Z(n, e2) {
2894
2899
  if (!e2.name) throw new Error("Event name is required");
2895
2900
  const [t2, o2] = e2.name.split(" ");
2896
2901
  if (!t2 || !o2) throw new Error("Event name is invalid");
2897
2902
  ++n.count;
2898
- const { timestamp: s2 = Date.now(), group: r2 = n.group, count: i2 = n.count } = e2, { name: a2 = `${t2} ${o2}`, data: c2 = {}, context: u2 = {}, globals: f2 = n.globals, custom: l2 = {}, user: g2 = n.user, nested: d2 = [], consent: m2 = n.consent, id: p2 = `${s2}-${r2}-${i2}`, trigger: h2 = "", entity: w2 = t2, action: y2 = o2, timing: b2 = 0, version: v2 = { source: n.version, tagging: n.config.tagging || 0 }, source: k2 = { type: "collector", id: "", previous_id: "" } } = e2;
2899
- return { name: a2, data: c2, context: u2, globals: f2, custom: l2, user: g2, nested: d2, consent: m2, id: p2, trigger: h2, entity: w2, action: y2, timestamp: s2, timing: b2, group: r2, count: i2, version: v2, source: k2 };
2903
+ const { timestamp: s2 = Date.now(), group: r2 = n.group, count: i2 = n.count } = e2, { name: a2 = `${t2} ${o2}`, data: c2 = {}, context: u2 = {}, globals: f2 = n.globals, custom: l2 = {}, user: g2 = n.user, nested: d2 = [], consent: m2 = n.consent, id: p2 = `${s2}-${r2}-${i2}`, trigger: h2 = "", entity: w2 = t2, action: b2 = o2, timing: y2 = 0, version: v2 = { source: n.version, tagging: n.config.tagging || 0 }, source: k2 = { type: "collector", id: "", previous_id: "" } } = e2;
2904
+ return { name: a2, data: c2, context: u2, globals: f2, custom: l2, user: g2, nested: d2, consent: m2, id: p2, trigger: h2, entity: w2, action: b2, timestamp: s2, timing: y2, group: r2, count: i2, version: v2, source: k2 };
2900
2905
  }
2901
2906
  async function nn(n, e2) {
2902
- n.allowed = true, n.count = 0, n.group = Q(), n.timing = Date.now(), e2 && (e2.consent && (n.consent = M(n.consent, e2.consent)), e2.user && (n.user = M(n.user, e2.user)), e2.globals && (n.globals = M(n.config.globalsStatic || {}, e2.globals)), e2.custom && (n.custom = M(n.custom, e2.custom))), Object.values(n.destinations).forEach((n2) => {
2907
+ n.allowed = true, n.count = 0, n.group = Q(), n.timing = Date.now(), e2 && (e2.consent && (n.consent = L(n.consent, e2.consent)), e2.user && (n.user = L(n.user, e2.user)), e2.globals && (n.globals = L(n.config.globalsStatic || {}, e2.globals)), e2.custom && (n.custom = L(n.custom, e2.custom))), Object.values(n.destinations).forEach((n2) => {
2903
2908
  n2.queuePush = [];
2904
2909
  }), n.queue = [], n.round++;
2905
2910
  return await U(n);
@@ -2911,15 +2916,15 @@ function rn(n, e2) {
2911
2916
  const l2 = i2 ? Object.freeze(i2) : void 0;
2912
2917
  if (c2) {
2913
2918
  const e3 = await tn(f2, c2, n);
2914
- if (e3.ignore) return N({ ok: true });
2919
+ if (e3.ignore) return J({ ok: true });
2915
2920
  if (c2.consent) {
2916
- if (!en(c2.consent, n.consent, e3.event.consent)) return N({ ok: true });
2921
+ if (!en(c2.consent, n.consent, e3.event.consent)) return J({ ok: true });
2917
2922
  }
2918
2923
  f2 = e3.event;
2919
2924
  }
2920
2925
  if (u2?.length && n.transformers && Object.keys(n.transformers).length > 0) {
2921
2926
  const e3 = await S(n, n.transformers, u2, f2, l2, a2);
2922
- if (null === e3) return N({ ok: true });
2927
+ if (null === e3) return J({ ok: true });
2923
2928
  f2 = e3;
2924
2929
  }
2925
2930
  const g2 = e2(f2), d2 = Z(n, g2), m2 = await U(n, d2, { id: r2, ingest: l2, respond: a2 });
@@ -2929,24 +2934,40 @@ function rn(n, e2) {
2929
2934
  e3.count++, e3.lastAt = Date.now(), e3.duration += Date.now() - s2;
2930
2935
  }
2931
2936
  return m2;
2932
- }, () => N({ ok: false }))(), "Push", n.hooks);
2937
+ }, () => J({ ok: false }))(), "Push", n.hooks);
2933
2938
  }
2934
2939
  async function un(n) {
2935
2940
  const e2 = r({ globalsStatic: {}, sessionStatic: {}, tagging: 0, run: true }, n, { merge: false, extend: false }), t2 = { level: n.logger?.level, handler: n.logger?.handler }, o2 = i(t2), s2 = { ...e2.globalsStatic, ...n.globals }, a2 = { allowed: false, config: e2, consent: n.consent || {}, count: 0, custom: n.custom || {}, destinations: {}, transformers: {}, stores: {}, globals: s2, group: "", hooks: {}, logger: o2, on: {}, queue: [], round: 0, session: void 0, status: { startedAt: Date.now(), in: 0, out: 0, failed: 0, sources: {}, destinations: {} }, timing: Date.now(), user: n.user || {}, version: "2.1.1", sources: {}, pending: { sources: {}, destinations: {} }, push: void 0, command: void 0 };
2936
- return a2.push = rn(a2, (n2) => ({ timing: Math.round((Date.now() - a2.timing) / 10) / 100, source: { type: "collector", id: "", previous_id: "" }, ...n2 })), a2.command = (function(n2, e3) {
2937
- return an(async (t3, o3, s3) => await cn(async () => await e3(n2, t3, o3, s3), () => N({ ok: false }))(), "Command", n2.hooks);
2938
- })(a2, Y), a2.stores = await (async function(n2, e3 = {}) {
2941
+ a2.push = rn(a2, (n2) => ({ timing: Math.round((Date.now() - a2.timing) / 10) / 100, source: { type: "collector", id: "", previous_id: "" }, ...n2 })), a2.command = (function(n2, e3) {
2942
+ return an(async (t3, o3, s3) => await cn(async () => await e3(n2, t3, o3, s3), () => J({ ok: false }))(), "Command", n2.hooks);
2943
+ })(a2, Y);
2944
+ const c2 = n.stores || {};
2945
+ return a2.stores = await (async function(n2, e3 = {}) {
2939
2946
  const t3 = {};
2940
2947
  for (const [o3, s3] of Object.entries(e3)) {
2941
- const { code: e4, config: r2 = {}, env: i2 = {} } = s3, a3 = n2.logger.scope("store").scope(o3), c2 = { collector: n2, logger: a3, id: o3, config: r2, env: i2 }, u2 = await e4(c2);
2948
+ const { code: e4, config: r2 = {}, env: i2 = {} } = s3, a3 = n2.logger.scope("store").scope(o3), c3 = { collector: n2, logger: a3, id: o3, config: r2, env: i2 }, u2 = await e4(c3);
2942
2949
  t3[o3] = u2;
2943
2950
  }
2944
2951
  return t3;
2945
- })(a2, n.stores || {}), a2.destinations = await z(a2, n.destinations || {}), a2.transformers = await (async function(n2, e3 = {}) {
2952
+ })(a2, c2), (function(n2, e3, t3) {
2953
+ const o3 = /* @__PURE__ */ new Map();
2954
+ for (const [t4, s4] of Object.entries(n2)) e3[t4] && o3.set(s4, e3[t4]);
2955
+ if (0 !== o3.size) {
2956
+ for (const n3 of [t3.transformers, t3.destinations, t3.sources]) if (n3) for (const e4 of Object.values(n3)) s3(e4.env);
2957
+ }
2958
+ function s3(n3) {
2959
+ if (n3) {
2960
+ for (const [e4, t4] of Object.entries(n3)) if ("object" == typeof t4 && null !== t4) {
2961
+ const s4 = o3.get(t4);
2962
+ s4 && (n3[e4] = s4);
2963
+ }
2964
+ }
2965
+ }
2966
+ })(c2, a2.stores, n), a2.destinations = await N(a2, n.destinations || {}), a2.transformers = await (async function(n2, e3 = {}) {
2946
2967
  const t3 = {};
2947
2968
  for (const [o3, s3] of Object.entries(e3)) {
2948
- const { code: e4, env: r2 = {} } = s3, { config: i2 } = A(s3, "next"), a3 = n2.logger.scope("transformer").scope(o3), c2 = { collector: n2, logger: a3, id: o3, config: i2, env: r2 }, u2 = await e4(c2);
2949
- t3[o3] = u2;
2969
+ const { code: e4, env: r2 = {} } = s3, { config: i2 } = A(s3, "next"), a3 = Object.keys(r2).length > 0 ? { ...i2, env: r2 } : i2, c3 = n2.logger.scope("transformer").scope(o3), u2 = { collector: n2, logger: c3, id: o3, config: a3, env: r2 }, f2 = await e4(u2);
2970
+ t3[o3] = f2;
2950
2971
  }
2951
2972
  return t3;
2952
2973
  })(a2, n.transformers || {}), a2;
@@ -2961,7 +2982,7 @@ async function fn(n) {
2961
2982
  let a3;
2962
2983
  if ("string" == typeof n2) a3 = { name: n2 }, e3 && "object" == typeof e3 && !Array.isArray(e3) && (a3.data = e3);
2963
2984
  else {
2964
- if (!n2 || "object" != typeof n2) return N({ ok: false });
2985
+ if (!n2 || "object" != typeof n2) return J({ ok: false });
2965
2986
  a3 = n2, e3 && "object" == typeof e3 && !Array.isArray(e3) && (a3.data = { ...a3.data || {}, ...e3 });
2966
2987
  }
2967
2988
  return s3 && "object" == typeof s3 && (a3.context = s3), r3 && Array.isArray(r3) && (a3.nested = r3), i3 && "object" == typeof i3 && (a3.custom = i3), o2.push(a3);
@@ -4072,6 +4093,91 @@ import { z as z2 } from "@walkeros/core/dev";
4072
4093
  var PortSchema = z2.number().int("Port must be an integer").min(1, "Port must be at least 1").max(65535, "Port must be at most 65535").describe("HTTP server port number");
4073
4094
  var FilePathSchema = z2.string().min(1, "File path cannot be empty").describe("Path to configuration file");
4074
4095
 
4096
+ // src/schemas/run.ts
4097
+ import { z as z3 } from "@walkeros/core/dev";
4098
+ var RunOptionsSchema = z3.object({
4099
+ flow: FilePathSchema,
4100
+ port: PortSchema.default(8080),
4101
+ flowName: z3.string().optional().describe("Specific flow name to run")
4102
+ });
4103
+
4104
+ // src/schemas/validate.ts
4105
+ import { z as z4 } from "@walkeros/core/dev";
4106
+ var ValidationTypeSchema = z4.enum(["contract", "event", "flow", "mapping"]).describe('Validation type: "event", "flow", "mapping", or "contract"');
4107
+ var ValidateOptionsSchema = z4.object({
4108
+ flow: z4.string().optional().describe("Flow name for multi-flow configs"),
4109
+ path: z4.string().optional().describe(
4110
+ 'Entry path for package schema validation (e.g., "destinations.snowplow", "sources.browser")'
4111
+ )
4112
+ });
4113
+ var ValidateInputShape = {
4114
+ type: ValidationTypeSchema,
4115
+ input: z4.string().min(1).describe("JSON string, file path, or URL to validate"),
4116
+ flow: z4.string().optional().describe("Flow name for multi-flow configs"),
4117
+ path: z4.string().optional().describe(
4118
+ 'Entry path for package schema validation (e.g., "destinations.snowplow"). When provided, validates the entry against its package JSON Schema instead of using --type.'
4119
+ )
4120
+ };
4121
+ var ValidateInputSchema = z4.object(ValidateInputShape);
4122
+
4123
+ // src/schemas/bundle.ts
4124
+ import { z as z5 } from "@walkeros/core/dev";
4125
+ var BundleOptionsSchema = z5.object({
4126
+ silent: z5.boolean().optional().describe("Suppress all output"),
4127
+ verbose: z5.boolean().optional().describe("Enable verbose logging"),
4128
+ stats: z5.boolean().optional().default(true).describe("Return bundle statistics"),
4129
+ cache: z5.boolean().optional().default(true).describe("Enable package caching"),
4130
+ flowName: z5.string().optional().describe("Flow name for multi-flow configs")
4131
+ });
4132
+ var BundleInputShape = {
4133
+ configPath: FilePathSchema.describe(
4134
+ "Path to flow configuration file (JSON or JavaScript)"
4135
+ ),
4136
+ flow: z5.string().optional().describe("Flow name for multi-flow configs"),
4137
+ stats: z5.boolean().optional().default(true).describe("Return bundle statistics"),
4138
+ output: z5.string().optional().describe("Output file path (defaults to config-defined)")
4139
+ };
4140
+ var BundleInputSchema = z5.object(BundleInputShape);
4141
+
4142
+ // src/schemas/simulate.ts
4143
+ import { z as z6 } from "@walkeros/core/dev";
4144
+ var PlatformSchema = z6.enum(["web", "server"]).describe("Platform type for event processing");
4145
+ var SimulateOptionsSchema = z6.object({
4146
+ silent: z6.boolean().optional().describe("Suppress all output"),
4147
+ verbose: z6.boolean().optional().describe("Enable verbose logging"),
4148
+ json: z6.boolean().optional().describe("Format output as JSON")
4149
+ });
4150
+ var SimulateInputShape = {
4151
+ configPath: FilePathSchema.describe("Path to flow configuration file"),
4152
+ event: z6.string().min(1).optional().describe(
4153
+ "Event as JSON string, file path, or URL. Optional when example is provided."
4154
+ ),
4155
+ flow: z6.string().optional().describe("Flow name for multi-flow configs"),
4156
+ platform: PlatformSchema.optional().describe("Override platform detection"),
4157
+ example: z6.string().optional().describe(
4158
+ 'Name of a step example to use as event input (uses its "in" value)'
4159
+ ),
4160
+ step: z6.string().optional().describe(
4161
+ 'Step target in type.name format (e.g. "destination.gtag") to narrow example lookup'
4162
+ )
4163
+ };
4164
+ var SimulateInputSchema = z6.object(SimulateInputShape);
4165
+
4166
+ // src/schemas/push.ts
4167
+ import { z as z7 } from "@walkeros/core/dev";
4168
+ var PushOptionsSchema = z7.object({
4169
+ silent: z7.boolean().optional().describe("Suppress all output"),
4170
+ verbose: z7.boolean().optional().describe("Enable verbose logging"),
4171
+ json: z7.boolean().optional().describe("Format output as JSON")
4172
+ });
4173
+ var PushInputShape = {
4174
+ configPath: FilePathSchema.describe("Path to flow configuration file"),
4175
+ event: z7.string().min(1).describe("Event as JSON string, file path, or URL"),
4176
+ flow: z7.string().optional().describe("Flow name for multi-flow configs"),
4177
+ platform: PlatformSchema.optional().describe("Override platform detection")
4178
+ };
4179
+ var PushInputSchema = z7.object(PushInputShape);
4180
+
4075
4181
  // src/commands/run/validators.ts
4076
4182
  function validateFlowFile(filePath) {
4077
4183
  const absolutePath = resolveAsset(filePath, "bundle");
@@ -4763,6 +4869,14 @@ init_config();
4763
4869
  import chalk2 from "chalk";
4764
4870
 
4765
4871
  // src/commands/validate/validators/contract.ts
4872
+ var SECTION_KEYS = ["globals", "context", "custom", "user", "consent"];
4873
+ var KNOWN_KEYS = /* @__PURE__ */ new Set([
4874
+ "extends",
4875
+ "tagging",
4876
+ "description",
4877
+ "events",
4878
+ ...SECTION_KEYS
4879
+ ]);
4766
4880
  function validateContract(input) {
4767
4881
  const errors = [];
4768
4882
  const warnings = [];
@@ -4770,32 +4884,108 @@ function validateContract(input) {
4770
4884
  if (typeof input !== "object" || input === null || Array.isArray(input)) {
4771
4885
  errors.push({
4772
4886
  path: "root",
4773
- message: "Contract must be an object",
4887
+ message: "Contract must be an object of named contract entries",
4774
4888
  code: "INVALID_CONTRACT"
4775
4889
  });
4776
4890
  return { valid: false, type: "contract", errors, warnings, details };
4777
4891
  }
4778
- const contract = input;
4779
- let entityCount = 0;
4780
- let actionCount = 0;
4781
- if ("$tagging" in contract) {
4782
- const tagging = contract.$tagging;
4783
- if (typeof tagging !== "number" || !Number.isInteger(tagging) || tagging < 0) {
4892
+ const contracts = input;
4893
+ const contractNames = Object.keys(contracts);
4894
+ details.contractCount = contractNames.length;
4895
+ for (const [name, entry] of Object.entries(contracts)) {
4896
+ if (typeof entry !== "object" || entry === null) {
4784
4897
  errors.push({
4785
- path: "$tagging",
4786
- message: "$tagging must be a non-negative integer",
4787
- value: tagging,
4788
- code: "INVALID_TAGGING"
4898
+ path: name,
4899
+ message: `Contract "${name}" must be an object`,
4900
+ code: "INVALID_CONTRACT_ENTRY"
4789
4901
  });
4790
- } else {
4791
- details.tagging = tagging;
4902
+ continue;
4903
+ }
4904
+ const obj = entry;
4905
+ if (obj.extends !== void 0) {
4906
+ if (typeof obj.extends !== "string") {
4907
+ errors.push({
4908
+ path: `${name}.extends`,
4909
+ message: "extends must be a string",
4910
+ code: "INVALID_EXTENDS"
4911
+ });
4912
+ } else if (!contractNames.includes(obj.extends)) {
4913
+ errors.push({
4914
+ path: `${name}.extends`,
4915
+ message: `extends references non-existent contract "${obj.extends}"`,
4916
+ value: obj.extends,
4917
+ code: "INVALID_EXTENDS"
4918
+ });
4919
+ }
4920
+ }
4921
+ if (obj.tagging !== void 0) {
4922
+ if (typeof obj.tagging !== "number" || !Number.isInteger(obj.tagging) || obj.tagging < 0) {
4923
+ errors.push({
4924
+ path: `${name}.tagging`,
4925
+ message: "tagging must be a non-negative integer",
4926
+ value: obj.tagging,
4927
+ code: "INVALID_TAGGING"
4928
+ });
4929
+ }
4930
+ }
4931
+ for (const key of SECTION_KEYS) {
4932
+ if (key in obj) {
4933
+ if (typeof obj[key] !== "object" || obj[key] === null) {
4934
+ errors.push({
4935
+ path: `${name}.${key}`,
4936
+ message: `Section "${key}" must be a JSON Schema object`,
4937
+ value: obj[key],
4938
+ code: "INVALID_SECTION"
4939
+ });
4940
+ }
4941
+ }
4942
+ }
4943
+ if (obj.events !== void 0) {
4944
+ if (typeof obj.events !== "object" || obj.events === null) {
4945
+ errors.push({
4946
+ path: `${name}.events`,
4947
+ message: "events must be an object",
4948
+ code: "INVALID_EVENTS"
4949
+ });
4950
+ } else {
4951
+ validateEntityActions(
4952
+ obj.events,
4953
+ `${name}.events`,
4954
+ errors
4955
+ );
4956
+ }
4792
4957
  }
4793
4958
  }
4794
- for (const [entityKey, entityValue] of Object.entries(contract)) {
4795
- if (entityKey.startsWith("$")) continue;
4959
+ for (const name of contractNames) {
4960
+ const visited = /* @__PURE__ */ new Set();
4961
+ let current = name;
4962
+ while (current) {
4963
+ if (visited.has(current)) {
4964
+ errors.push({
4965
+ path: `${name}.extends`,
4966
+ message: `Circular extends chain: ${[...visited, current].join(" \u2192 ")}`,
4967
+ code: "CIRCULAR_EXTENDS"
4968
+ });
4969
+ break;
4970
+ }
4971
+ visited.add(current);
4972
+ const entry = contracts[current];
4973
+ current = entry?.extends || "";
4974
+ }
4975
+ }
4976
+ return {
4977
+ valid: errors.length === 0,
4978
+ type: "contract",
4979
+ errors,
4980
+ warnings,
4981
+ details
4982
+ };
4983
+ }
4984
+ function validateEntityActions(obj, prefix, errors) {
4985
+ for (const [entityKey, entityValue] of Object.entries(obj)) {
4796
4986
  if (entityKey.trim() === "") {
4797
4987
  errors.push({
4798
- path: entityKey,
4988
+ path: `${prefix}.${entityKey}`,
4799
4989
  message: "Entity key cannot be empty",
4800
4990
  code: "INVALID_ENTITY_KEY"
4801
4991
  });
@@ -4803,19 +4993,19 @@ function validateContract(input) {
4803
4993
  }
4804
4994
  if (typeof entityValue !== "object" || entityValue === null) {
4805
4995
  errors.push({
4806
- path: entityKey,
4807
- message: `Entity "${entityKey}" must be an object of action entries`,
4996
+ path: `${prefix}.${entityKey}`,
4997
+ message: `Entity "${entityKey}" must be an object`,
4808
4998
  value: entityValue,
4809
4999
  code: "INVALID_ENTITY"
4810
5000
  });
4811
5001
  continue;
4812
5002
  }
4813
- entityCount++;
4814
- const actions = entityValue;
4815
- for (const [actionKey, actionValue] of Object.entries(actions)) {
5003
+ for (const [actionKey, actionValue] of Object.entries(
5004
+ entityValue
5005
+ )) {
4816
5006
  if (actionKey.trim() === "") {
4817
5007
  errors.push({
4818
- path: `${entityKey}.${actionKey}`,
5008
+ path: `${prefix}.${entityKey}.${actionKey}`,
4819
5009
  message: "Action key cannot be empty",
4820
5010
  code: "INVALID_ACTION_KEY"
4821
5011
  });
@@ -4823,25 +5013,14 @@ function validateContract(input) {
4823
5013
  }
4824
5014
  if (typeof actionValue !== "object" || actionValue === null || Array.isArray(actionValue)) {
4825
5015
  errors.push({
4826
- path: `${entityKey}.${actionKey}`,
4827
- message: `Contract entry must be a JSON Schema object`,
5016
+ path: `${prefix}.${entityKey}.${actionKey}`,
5017
+ message: "Contract entry must be a JSON Schema object",
4828
5018
  value: typeof actionValue,
4829
5019
  code: "INVALID_SCHEMA_ENTRY"
4830
5020
  });
4831
- continue;
4832
5021
  }
4833
- actionCount++;
4834
5022
  }
4835
5023
  }
4836
- details.entityCount = entityCount;
4837
- details.actionCount = actionCount;
4838
- return {
4839
- valid: errors.length === 0,
4840
- type: "contract",
4841
- errors,
4842
- warnings,
4843
- details
4844
- };
4845
5024
  }
4846
5025
 
4847
5026
  // src/commands/validate/validators/event.ts
@@ -4995,23 +5174,38 @@ function validateFlow(input, options = {}) {
4995
5174
  for (const name of flowsToCheck) {
4996
5175
  const flowSettings = flows[name];
4997
5176
  if (!flowSettings) continue;
4998
- checkExampleCoverage(flowSettings, warnings);
4999
5177
  const connections = buildConnectionGraph(flowSettings);
5000
5178
  for (const conn of connections) {
5001
5179
  checkCompatibility(conn, errors, warnings);
5002
5180
  }
5003
5181
  totalConnections += connections.length;
5004
- const setupContract = config.contract;
5005
- if (setupContract || flowSettings.contract) {
5006
- checkContractCompliance(
5007
- flowSettings,
5008
- setupContract,
5009
- flowSettings.contract,
5010
- warnings
5011
- );
5182
+ const contract = config.contract;
5183
+ if (contract) {
5184
+ checkContractCompliance(flowSettings, contract, warnings);
5012
5185
  }
5013
5186
  }
5014
5187
  details.connectionsChecked = totalConnections;
5188
+ for (const name of flowsToCheck) {
5189
+ const flowSettings = flows[name];
5190
+ if (!flowSettings) continue;
5191
+ for (const [destName, dest] of Object.entries(
5192
+ flowSettings.destinations || {}
5193
+ )) {
5194
+ const destConfig = dest;
5195
+ const mapping = destConfig.config?.mapping;
5196
+ if (!mapping || typeof mapping !== "object") continue;
5197
+ for (const key of Object.keys(mapping)) {
5198
+ if (key.includes(".") && !key.includes(" ")) {
5199
+ const parts = key.split(".");
5200
+ warnings.push({
5201
+ path: `destination.${destName}.config.mapping`,
5202
+ message: `Mapping key "${key}" looks like dot-notation. Mapping uses nested entity \u2192 action structure.`,
5203
+ suggestion: `Use nested format: { "${parts[0]}": { "${parts.slice(1).join(".")}": { ... } } }`
5204
+ });
5205
+ }
5206
+ }
5207
+ }
5208
+ }
5015
5209
  }
5016
5210
  return {
5017
5211
  valid: errors.length === 0,
@@ -5021,26 +5215,6 @@ function validateFlow(input, options = {}) {
5021
5215
  details
5022
5216
  };
5023
5217
  }
5024
- function checkExampleCoverage(config, warnings) {
5025
- const stepTypes = [
5026
- { key: "sources", type: "source" },
5027
- { key: "transformers", type: "transformer" },
5028
- { key: "destinations", type: "destination" }
5029
- ];
5030
- for (const { key, type } of stepTypes) {
5031
- const refs = config[key];
5032
- if (!refs) continue;
5033
- for (const [name, ref] of Object.entries(refs)) {
5034
- if (!ref.examples || Object.keys(ref.examples).length === 0) {
5035
- warnings.push({
5036
- path: `${type}.${name}`,
5037
- message: `Step has no examples`,
5038
- suggestion: `Add examples to ${type}.${name} for testing and documentation`
5039
- });
5040
- }
5041
- }
5042
- }
5043
- }
5044
5218
  function buildConnectionGraph(config) {
5045
5219
  const connections = [];
5046
5220
  for (const [name, source] of Object.entries(config.sources || {})) {
@@ -5142,16 +5316,16 @@ function isStructurallyCompatible(a2, b2) {
5142
5316
  }
5143
5317
  return true;
5144
5318
  }
5145
- function checkContractCompliance(config, setupContract, flowContract, warnings) {
5319
+ function checkContractCompliance(config, contract, warnings) {
5146
5320
  for (const [name, dest] of Object.entries(config.destinations || {})) {
5147
5321
  if (!dest.examples) continue;
5148
5322
  for (const [exName, example] of Object.entries(dest.examples)) {
5149
5323
  if (!example.in || typeof example.in !== "object") continue;
5150
5324
  const event = example.in;
5151
5325
  if (!event.entity || !event.action) continue;
5152
- const contract = flowContract?.[event.entity] || setupContract?.[event.entity];
5153
- if (!contract || typeof contract !== "object") continue;
5154
- const actionSchema = contract[event.action] || contract["*"];
5326
+ const entityContract = contract[event.entity];
5327
+ if (!entityContract || typeof entityContract !== "object") continue;
5328
+ const actionSchema = entityContract[event.action] || entityContract["*"];
5155
5329
  if (actionSchema) {
5156
5330
  warnings.push({
5157
5331
  path: `destination.${name}.examples.${exName}`,