@walkeros/cli 2.1.1 → 2.2.0-next-1772811722420

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
@@ -1,11 +1,5 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __getOwnPropNames = Object.getOwnPropertyNames;
3
- var __require = /* @__PURE__ */ ((x2) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x2, {
4
- get: (a2, b2) => (typeof require !== "undefined" ? require : a2)[b2]
5
- }) : x2)(function(x2) {
6
- if (typeof require !== "undefined") return require.apply(this, arguments);
7
- throw Error('Dynamic require of "' + x2 + '" is not supported');
8
- });
9
3
  var __esm = (fn2, res) => function __init() {
10
4
  return fn2 && (res = (0, fn2[__getOwnPropNames(fn2)[0]])(fn2 = 0)), res;
11
5
  };
@@ -297,8 +291,8 @@ var init_heartbeat = __esm({
297
291
 
298
292
  // src/commands/bundle/index.ts
299
293
  init_cli_logger();
300
- import path10 from "path";
301
- import fs10 from "fs-extra";
294
+ import path11 from "path";
295
+ import fs11 from "fs-extra";
302
296
  import { getPlatform as getPlatform2 } from "@walkeros/core";
303
297
 
304
298
  // src/core/index.ts
@@ -661,8 +655,8 @@ function validateFlowSetup(data) {
661
655
  const result = safeParseSetup(data);
662
656
  if (!result.success) {
663
657
  const errors = result.error.issues.map((issue) => {
664
- const path14 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
665
- return ` - ${path14}: ${issue.message}`;
658
+ const path15 = issue.path.length > 0 ? issue.path.map(String).join(".") : "root";
659
+ return ` - ${path15}: ${issue.message}`;
666
660
  }).join("\n");
667
661
  throw new Error(`Invalid configuration:
668
662
  ${errors}`);
@@ -1096,11 +1090,18 @@ async function copyIncludes(includes, sourceDir, outputDir, logger2) {
1096
1090
  const sourcePath = path9.resolve(sourceDir, include);
1097
1091
  const folderName = path9.basename(include);
1098
1092
  const destPath = path9.join(outputDir, folderName);
1093
+ const resolvedOutput = path9.resolve(outputDir);
1094
+ const resolvedSource = path9.resolve(sourcePath);
1095
+ if (resolvedSource === resolvedOutput || resolvedOutput.startsWith(resolvedSource + path9.sep) || resolvedSource.startsWith(resolvedOutput + path9.sep)) {
1096
+ throw new Error(
1097
+ `Circular include detected: "${include}" resolves to "${resolvedSource}" which overlaps with output directory "${resolvedOutput}"`
1098
+ );
1099
+ }
1099
1100
  if (await fs8.pathExists(sourcePath)) {
1100
1101
  await fs8.copy(sourcePath, destPath);
1101
1102
  logger2.debug(`Copied ${include} to output`);
1102
1103
  } else {
1103
- logger2.debug(`Include folder not found: ${include}`);
1104
+ logger2.warn(`Include folder not found: ${include}`);
1104
1105
  }
1105
1106
  }
1106
1107
  }
@@ -1449,6 +1450,18 @@ function detectTransformerPackages(flowConfig) {
1449
1450
  }
1450
1451
  return transformerPackages;
1451
1452
  }
1453
+ function detectStorePackages(flowConfig) {
1454
+ const storePackages = /* @__PURE__ */ new Set();
1455
+ const stores = flowConfig.stores;
1456
+ if (stores) {
1457
+ for (const [, storeConfig] of Object.entries(stores)) {
1458
+ if (typeof storeConfig === "object" && storeConfig !== null && "package" in storeConfig && typeof storeConfig.package === "string") {
1459
+ storePackages.add(storeConfig.package);
1460
+ }
1461
+ }
1462
+ }
1463
+ return storePackages;
1464
+ }
1452
1465
  function detectExplicitCodeImports(flowConfig) {
1453
1466
  const explicitCodeImports = /* @__PURE__ */ new Map();
1454
1467
  const destinations = flowConfig.destinations;
@@ -1504,15 +1517,30 @@ function detectExplicitCodeImports(flowConfig) {
1504
1517
  }
1505
1518
  }
1506
1519
  }
1520
+ const stores = flowConfig.stores;
1521
+ if (stores) {
1522
+ for (const [, storeConfig] of Object.entries(stores)) {
1523
+ if (typeof storeConfig === "object" && storeConfig !== null && "package" in storeConfig && typeof storeConfig.package === "string" && "code" in storeConfig && typeof storeConfig.code === "string") {
1524
+ const isAutoGenerated = storeConfig.code.startsWith("_");
1525
+ if (!isAutoGenerated) {
1526
+ if (!explicitCodeImports.has(storeConfig.package)) {
1527
+ explicitCodeImports.set(storeConfig.package, /* @__PURE__ */ new Set());
1528
+ }
1529
+ explicitCodeImports.get(storeConfig.package).add(storeConfig.code);
1530
+ }
1531
+ }
1532
+ }
1533
+ }
1507
1534
  return explicitCodeImports;
1508
1535
  }
1509
- function generateImportStatements(packages, destinationPackages, sourcePackages, transformerPackages, explicitCodeImports) {
1536
+ function generateImportStatements(packages, destinationPackages, sourcePackages, transformerPackages, storePackages, explicitCodeImports) {
1510
1537
  const importStatements = [];
1511
1538
  const examplesMappings = [];
1512
1539
  const usedPackages = /* @__PURE__ */ new Set([
1513
1540
  ...destinationPackages,
1514
1541
  ...sourcePackages,
1515
- ...transformerPackages
1542
+ ...transformerPackages,
1543
+ ...storePackages
1516
1544
  ]);
1517
1545
  for (const [packageName, packageConfig] of Object.entries(packages)) {
1518
1546
  const isUsedByDestOrSource = usedPackages.has(packageName);
@@ -1568,16 +1596,74 @@ function generateImportStatements(packages, destinationPackages, sourcePackages,
1568
1596
  }
1569
1597
  return { importStatements, examplesMappings };
1570
1598
  }
1599
+ var VALID_JS_IDENTIFIER = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/;
1600
+ function validateComponentNames(components, section) {
1601
+ for (const name of Object.keys(components)) {
1602
+ if (!VALID_JS_IDENTIFIER.test(name)) {
1603
+ throw new Error(
1604
+ `Invalid ${section} name "${name}": must be a valid JavaScript identifier (use camelCase, e.g., "${name.replace(/-([a-z])/g, (_2, c2) => c2.toUpperCase())}")`
1605
+ );
1606
+ }
1607
+ }
1608
+ }
1609
+ function validateStoreReferences(flowConfig, storeIds) {
1610
+ const refs = [];
1611
+ function collectRefs(obj, path15) {
1612
+ if (typeof obj === "string" && obj.startsWith("$store:")) {
1613
+ refs.push({ ref: obj.slice(7), location: path15 });
1614
+ } else if (obj && typeof obj === "object") {
1615
+ for (const [key, val] of Object.entries(obj)) {
1616
+ collectRefs(val, `${path15}.${key}`);
1617
+ }
1618
+ }
1619
+ }
1620
+ for (const [section, components] of Object.entries({
1621
+ sources: flowConfig.sources || {},
1622
+ destinations: flowConfig.destinations || {},
1623
+ transformers: flowConfig.transformers || {}
1624
+ })) {
1625
+ for (const [id, component] of Object.entries(
1626
+ components
1627
+ )) {
1628
+ collectRefs(component, `${section}.${id}`);
1629
+ }
1630
+ }
1631
+ for (const { ref, location } of refs) {
1632
+ if (!storeIds.has(ref)) {
1633
+ const available = storeIds.size > 0 ? `Available stores: ${Array.from(storeIds).join(", ")}` : "No stores defined";
1634
+ throw new Error(
1635
+ `Store reference "$store:${ref}" in ${location} \u2014 store "${ref}" not found. ${available}`
1636
+ );
1637
+ }
1638
+ }
1639
+ }
1571
1640
  async function createEntryPoint(flowConfig, buildOptions, packagePaths) {
1572
1641
  const destinationPackages = detectDestinationPackages(flowConfig);
1573
1642
  const sourcePackages = detectSourcePackages(flowConfig);
1574
1643
  const transformerPackages = detectTransformerPackages(flowConfig);
1644
+ const storePackages = detectStorePackages(flowConfig);
1575
1645
  const explicitCodeImports = detectExplicitCodeImports(flowConfig);
1646
+ const storeIds = new Set(
1647
+ Object.keys(
1648
+ flowConfig.stores || {}
1649
+ )
1650
+ );
1651
+ validateStoreReferences(flowConfig, storeIds);
1652
+ const flowWithSections = flowConfig;
1653
+ if (flowWithSections.sources)
1654
+ validateComponentNames(flowWithSections.sources, "sources");
1655
+ if (flowWithSections.destinations)
1656
+ validateComponentNames(flowWithSections.destinations, "destinations");
1657
+ if (flowWithSections.transformers)
1658
+ validateComponentNames(flowWithSections.transformers, "transformers");
1659
+ if (flowWithSections.stores)
1660
+ validateComponentNames(flowWithSections.stores, "stores");
1576
1661
  const { importStatements } = generateImportStatements(
1577
1662
  buildOptions.packages,
1578
1663
  destinationPackages,
1579
1664
  sourcePackages,
1580
1665
  transformerPackages,
1666
+ storePackages,
1581
1667
  explicitCodeImports
1582
1668
  );
1583
1669
  const importsCode = importStatements.join("\n");
@@ -1630,6 +1716,7 @@ function buildConfigObject(flowConfig, explicitCodeImports) {
1630
1716
  const sources = flowWithProps.sources || {};
1631
1717
  const destinations = flowWithProps.destinations || {};
1632
1718
  const transformers = flowWithProps.transformers || {};
1719
+ const stores = flowWithProps.stores || {};
1633
1720
  Object.entries(sources).forEach(([name, source]) => {
1634
1721
  if (source.code !== true) {
1635
1722
  validateReference("Source", name, source);
@@ -1711,11 +1798,38 @@ function buildConfigObject(flowConfig, explicitCodeImports) {
1711
1798
  config: ${configStr}${envStr}${nextStr}
1712
1799
  }`;
1713
1800
  });
1801
+ Object.entries(stores).forEach(([name, store]) => {
1802
+ if (store.package || isInlineCode(store.code)) {
1803
+ validateReference("Store", name, store);
1804
+ }
1805
+ });
1806
+ const storesEntries = Object.entries(stores).filter(([, store]) => store.package || isInlineCode(store.code)).map(([key, store]) => {
1807
+ if (isInlineCode(store.code)) {
1808
+ return ` ${key}: ${generateInlineCode(store.code, store.config || {}, store.env)}`;
1809
+ }
1810
+ let codeVar;
1811
+ if (store.code && typeof store.code === "string" && explicitCodeImports.has(store.package)) {
1812
+ codeVar = store.code;
1813
+ } else {
1814
+ codeVar = packageNameToVariable(store.package);
1815
+ }
1816
+ const configStr = store.config ? processConfigValue(store.config) : "{}";
1817
+ const envStr = store.env ? `,
1818
+ env: ${processConfigValue(store.env)}` : "";
1819
+ return ` ${key}: {
1820
+ code: ${codeVar},
1821
+ config: ${configStr}${envStr}
1822
+ }`;
1823
+ });
1714
1824
  const collectorStr = flowWithProps.collector ? `,
1715
1825
  ...${processConfigValue(flowWithProps.collector)}` : "";
1716
1826
  const transformersStr = transformersEntries.length > 0 ? `,
1717
1827
  transformers: {
1718
1828
  ${transformersEntries.join(",\n")}
1829
+ }` : "";
1830
+ const storesStr = storesEntries.length > 0 ? `,
1831
+ stores: {
1832
+ ${storesEntries.join(",\n")}
1719
1833
  }` : "";
1720
1834
  return `{
1721
1835
  sources: {
@@ -1723,7 +1837,7 @@ ${sourcesEntries.join(",\n")}
1723
1837
  },
1724
1838
  destinations: {
1725
1839
  ${destinationsEntries.join(",\n")}
1726
- }${transformersStr}${collectorStr}
1840
+ }${transformersStr}${storesStr}${collectorStr}
1727
1841
  }`;
1728
1842
  }
1729
1843
  function processConfigValue(value) {
@@ -1733,6 +1847,10 @@ function serializeWithCode(value, indent) {
1733
1847
  const spaces = " ".repeat(indent);
1734
1848
  const nextSpaces = " ".repeat(indent + 1);
1735
1849
  if (typeof value === "string") {
1850
+ if (value.startsWith("$store:")) {
1851
+ const storeId = value.slice(7);
1852
+ return `stores.${storeId}`;
1853
+ }
1736
1854
  if (value.startsWith("$code:")) {
1737
1855
  return value.slice(6);
1738
1856
  }
@@ -1909,13 +2027,43 @@ function createApiClient() {
1909
2027
  });
1910
2028
  }
1911
2029
 
2030
+ // src/commands/bundle/dockerfile.ts
2031
+ import path10 from "path";
2032
+ import fs10 from "fs-extra";
2033
+ function buildDockerfileContent(platform, includedFolders) {
2034
+ const bundleFile = platform === "web" ? "walker.js" : "bundle.mjs";
2035
+ const lines = [
2036
+ "# Generated by walkeros CLI",
2037
+ "FROM walkeros/flow:latest",
2038
+ "",
2039
+ `COPY ${bundleFile} /app/flow/${bundleFile}`
2040
+ ];
2041
+ for (const folder of includedFolders) {
2042
+ const name = path10.basename(folder);
2043
+ lines.push(`COPY ${name}/ /app/flow/${name}/`);
2044
+ }
2045
+ lines.push("", `ENV BUNDLE=/app/flow/${bundleFile}`, "", "EXPOSE 8080", "");
2046
+ return lines.join("\n");
2047
+ }
2048
+ async function generateDockerfile(outputDir, platform, logger2, customFile, includedFolders) {
2049
+ const destPath = path10.join(outputDir, "Dockerfile");
2050
+ if (customFile && await fs10.pathExists(customFile)) {
2051
+ await fs10.copy(customFile, destPath);
2052
+ logger2.info(`Dockerfile: ${destPath} (copied from ${customFile})`);
2053
+ return;
2054
+ }
2055
+ const dockerfile = buildDockerfileContent(platform, includedFolders || []);
2056
+ await fs10.writeFile(destPath, dockerfile);
2057
+ logger2.info(`Dockerfile: ${destPath}`);
2058
+ }
2059
+
1912
2060
  // src/commands/bundle/index.ts
1913
2061
  function resolveOutputPath(output, buildOptions) {
1914
- const resolved = path10.resolve(output);
1915
- const ext = path10.extname(resolved);
1916
- if (output.endsWith("/") || output.endsWith(path10.sep) || !ext) {
2062
+ const resolved = path11.resolve(output);
2063
+ const ext = path11.extname(resolved);
2064
+ if (output.endsWith("/") || output.endsWith(path11.sep) || !ext) {
1917
2065
  const filename = buildOptions.platform === "browser" ? "walker.js" : "bundle.mjs";
1918
- return path10.join(resolved, filename);
2066
+ return path11.join(resolved, filename);
1919
2067
  }
1920
2068
  return resolved;
1921
2069
  }
@@ -1945,7 +2093,7 @@ async function bundleCommand(options) {
1945
2093
  } catch {
1946
2094
  throw new Error("Invalid JSON received on stdin");
1947
2095
  }
1948
- configPath = path10.resolve(process.cwd(), "stdin.config.json");
2096
+ configPath = path11.resolve(process.cwd(), "stdin.config.json");
1949
2097
  } else {
1950
2098
  const file = options.config || "bundle.config.json";
1951
2099
  configPath = resolveAsset(file, "config");
@@ -1999,21 +2147,27 @@ async function bundleCommand(options) {
1999
2147
  if (uploadUrl) {
2000
2148
  await uploadBundleToUrl(buildOptions.output, uploadUrl);
2001
2149
  logger2.info(`Uploaded to: ${sanitizeUrl(uploadUrl)}`);
2002
- await fs10.remove(buildOptions.output);
2150
+ await fs11.remove(buildOptions.output);
2003
2151
  }
2004
2152
  if (!options.json && !options.all && options.stats && stats) {
2005
2153
  displayStats(stats, logger2);
2006
2154
  }
2007
2155
  if (writingToStdout && !options.json) {
2008
- const bundleContent = await fs10.readFile(buildOptions.output);
2156
+ const bundleContent = await fs11.readFile(buildOptions.output);
2009
2157
  await writeResult(bundleContent, {});
2010
2158
  }
2011
2159
  if (options.dockerfile && options.output) {
2012
2160
  const platform = getPlatform2(flowConfig);
2013
2161
  if (platform) {
2014
- const outputDir = path10.dirname(buildOptions.output);
2162
+ const outputDir = path11.dirname(buildOptions.output);
2015
2163
  const customFile = typeof options.dockerfile === "string" ? options.dockerfile : void 0;
2016
- await generateDockerfile(outputDir, platform, logger2, customFile);
2164
+ await generateDockerfile(
2165
+ outputDir,
2166
+ platform,
2167
+ logger2,
2168
+ customFile,
2169
+ buildOptions.include
2170
+ );
2017
2171
  }
2018
2172
  }
2019
2173
  } catch (error) {
@@ -2076,7 +2230,7 @@ Build Summary: ${successCount}/${results.length} succeeded`
2076
2230
  }
2077
2231
  async function bundle(configOrPath, options = {}) {
2078
2232
  let rawConfig;
2079
- let configPath = path10.resolve(process.cwd(), "walkeros.config.json");
2233
+ let configPath = path11.resolve(process.cwd(), "walkeros.config.json");
2080
2234
  if (typeof configOrPath === "string") {
2081
2235
  configPath = resolveAsset(configOrPath, "config");
2082
2236
  rawConfig = await loadJsonConfig(configPath);
@@ -2099,27 +2253,6 @@ async function bundle(configOrPath, options = {}) {
2099
2253
  options.stats ?? false
2100
2254
  );
2101
2255
  }
2102
- async function generateDockerfile(outputDir, platform, logger2, customFile) {
2103
- const destPath = path10.join(outputDir, "Dockerfile");
2104
- if (customFile && await fs10.pathExists(customFile)) {
2105
- await fs10.copy(customFile, destPath);
2106
- logger2.info(`Dockerfile: ${destPath} (copied from ${customFile})`);
2107
- return;
2108
- }
2109
- const isWeb = platform === "web";
2110
- const bundleFile = isWeb ? "walker.js" : "bundle.mjs";
2111
- const dockerfile = `# Generated by walkeros CLI
2112
- FROM walkeros/flow:latest
2113
-
2114
- COPY ${bundleFile} /app/flow/${bundleFile}
2115
-
2116
- ENV BUNDLE=/app/flow/${bundleFile}
2117
-
2118
- EXPOSE 8080
2119
- `;
2120
- await fs10.writeFile(destPath, dockerfile);
2121
- logger2.info(`Dockerfile: ${destPath}`);
2122
- }
2123
2256
  async function bundleRemote(options) {
2124
2257
  const client = createApiClient();
2125
2258
  const body = { flow: options.content };
@@ -2140,13 +2273,12 @@ async function bundleRemote(options) {
2140
2273
  }
2141
2274
 
2142
2275
  // src/commands/simulate/simulator.ts
2143
- import fs11 from "fs-extra";
2144
- import { Level as Level2 } from "@walkeros/core";
2276
+ import fs12 from "fs-extra";
2145
2277
 
2146
2278
  // ../collector/dist/index.mjs
2147
2279
  import { assign as o } from "@walkeros/core";
2148
- import { assign as i, createLogger as r } from "@walkeros/core";
2149
- import { assign as a, clone as c, debounce as u, getId as f, getGrantedConsent as l, isDefined as d, isFunction as g, isObject as m, processEventMapping as p, tryCatchAsync as h, useHooks as w } from "@walkeros/core";
2280
+ import { assign as r, createLogger as i } from "@walkeros/core";
2281
+ 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";
2150
2282
  import { isArray as y } from "@walkeros/core";
2151
2283
  import { tryCatch as b, tryCatchAsync as v } from "@walkeros/core";
2152
2284
  import { getMappingValue as k, tryCatchAsync as C } from "@walkeros/core";
@@ -2192,22 +2324,22 @@ function E(n, e2 = {}) {
2192
2324
  }
2193
2325
  async function P(n, e2, t2) {
2194
2326
  if (e2.init && !e2.config.init) {
2195
- const o2 = e2.type || "unknown", s2 = n.logger.scope(`transformer:${o2}`), i2 = { collector: n, logger: s2, id: t2, config: e2.config, env: $(e2.config.env) };
2327
+ const o2 = e2.type || "unknown", s2 = n.logger.scope(`transformer:${o2}`), r2 = { collector: n, logger: s2, id: t2, config: e2.config, env: $(e2.config.env) };
2196
2328
  s2.debug("init");
2197
- const r2 = await j(e2.init, "TransformerInit", n.hooks)(i2);
2198
- if (false === r2) return false;
2199
- e2.config = { ...r2 || e2.config, init: true }, s2.debug("init done");
2329
+ const i2 = await j(e2.init, "TransformerInit", n.hooks)(r2);
2330
+ if (false === i2) return false;
2331
+ e2.config = { ...i2 || e2.config, init: true }, s2.debug("init done");
2200
2332
  }
2201
2333
  return true;
2202
2334
  }
2203
- async function x(n, e2, t2, o2, s2, i2) {
2204
- const r2 = e2.type || "unknown", a2 = n.logger.scope(`transformer:${r2}`), c2 = { collector: n, logger: a2, id: t2, ingest: s2, config: e2.config, env: { ...$(e2.config.env), ...i2 ? { respond: i2 } : {} } };
2335
+ async function x(n, e2, t2, o2, s2, r2) {
2336
+ const i2 = e2.type || "unknown", a2 = n.logger.scope(`transformer:${i2}`), c2 = { collector: n, logger: a2, id: t2, ingest: s2, config: e2.config, env: { ...$(e2.config.env), ...r2 ? { respond: r2 } : {} } };
2205
2337
  a2.debug("push", { event: o2.name });
2206
2338
  const u2 = await j(e2.push, "TransformerPush", n.hooks)(o2, c2);
2207
2339
  return a2.debug("push done"), u2;
2208
2340
  }
2209
- async function S(n, e2, t2, o2, s2, i2) {
2210
- let r2 = o2, a2 = i2;
2341
+ async function S(n, e2, t2, o2, s2, r2) {
2342
+ let i2 = o2, a2 = r2;
2211
2343
  for (const o3 of t2) {
2212
2344
  const t3 = e2[o3];
2213
2345
  if (!t3) {
@@ -2215,33 +2347,33 @@ async function S(n, e2, t2, o2, s2, i2) {
2215
2347
  continue;
2216
2348
  }
2217
2349
  if (!await q(P)(n, t3, o3)) return n.logger.error(`Transformer init failed: ${o3}`), null;
2218
- const i3 = await q(x, (e3) => (n.logger.scope(`transformer:${t3.type || "unknown"}`).error("Push failed", { error: e3 }), false))(n, t3, o3, r2, s2, a2);
2219
- if (false === i3) return null;
2220
- if (i3 && "object" == typeof i3) {
2221
- const { event: t4, respond: o4, next: c2 } = i3;
2350
+ const r3 = await q(x, (e3) => (n.logger.scope(`transformer:${t3.type || "unknown"}`).error("Push failed", { error: e3 }), false))(n, t3, o3, i2, s2, a2);
2351
+ if (false === r3) return null;
2352
+ if (r3 && "object" == typeof r3) {
2353
+ const { event: t4, respond: o4, next: c2 } = r3;
2222
2354
  if (o4 && (a2 = o4), c2) {
2223
2355
  const o5 = E(c2, D(e2));
2224
- return o5.length > 0 ? S(n, e2, o5, t4 || r2, s2, a2) : (n.logger.warn(`Branch target not found: ${JSON.stringify(c2)}`), null);
2356
+ return o5.length > 0 ? S(n, e2, o5, t4 || i2, s2, a2) : (n.logger.warn(`Branch target not found: ${JSON.stringify(c2)}`), null);
2225
2357
  }
2226
- t4 && (r2 = t4);
2358
+ t4 && (i2 = t4);
2227
2359
  }
2228
2360
  }
2229
- return r2;
2361
+ return i2;
2230
2362
  }
2231
2363
  function $(n) {
2232
2364
  return n && O(n) ? n : {};
2233
2365
  }
2234
2366
  async function R(n, e2, t2) {
2235
- const { code: o2, config: s2 = {}, env: i2 = {}, primary: r2, next: a2 } = t2;
2367
+ const { code: o2, config: s2 = {}, env: r2 = {}, primary: i2, next: a2 } = t2;
2236
2368
  let c2, u2;
2237
- const f2 = E(a2, D(n.transformers)), l2 = n.logger.scope("source").scope(e2), d2 = { push: (t3, o3 = {}) => n.push(t3, { ...o3, id: e2, ingest: c2, respond: u2, mapping: s2, preChain: f2 }), command: n.command, sources: n.sources, elb: n.sources.elb.push, logger: l2, ...i2 }, g2 = { collector: n, logger: l2, id: e2, config: s2, env: d2, setIngest: async (e3) => {
2369
+ const f2 = E(a2, D(n.transformers)), l2 = n.logger.scope("source").scope(e2), g2 = { push: (t3, o3 = {}) => n.push(t3, { ...o3, id: e2, ingest: c2, respond: u2, mapping: s2, preChain: f2 }), command: n.command, sources: n.sources, elb: n.sources.elb.push, logger: l2, ...r2 }, d2 = { collector: n, logger: l2, id: e2, config: s2, env: g2, setIngest: async (e3) => {
2238
2370
  c2 = s2.ingest ? await k(e3, s2.ingest, { collector: n }) : void 0;
2239
2371
  }, setRespond: (n2) => {
2240
2372
  u2 = n2;
2241
- } }, m2 = await C(o2)(g2);
2373
+ } }, m2 = await C(o2)(d2);
2242
2374
  if (!m2) return;
2243
2375
  const p2 = m2.type || "unknown", h2 = n.logger.scope(p2).scope(e2);
2244
- return d2.logger = h2, r2 && (m2.config = { ...m2.config, primary: r2 }), m2;
2376
+ return g2.logger = h2, i2 && (m2.config = { ...m2.config, primary: i2 }), m2;
2245
2377
  }
2246
2378
  async function T(n, e2 = {}) {
2247
2379
  const t2 = {};
@@ -2251,81 +2383,81 @@ async function T(n, e2 = {}) {
2251
2383
  n.pending.sources[o2] = s2;
2252
2384
  continue;
2253
2385
  }
2254
- const i2 = await R(n, o2, s2);
2255
- i2 && (t2[o2] = i2);
2386
+ const r2 = await R(n, o2, s2);
2387
+ r2 && (t2[o2] = r2);
2256
2388
  }
2257
2389
  return t2;
2258
2390
  }
2259
2391
  async function I(n, e2, t2) {
2260
- const o2 = n.on, s2 = o2[e2] || [], i2 = y(t2) ? t2 : [t2];
2261
- i2.forEach((n2) => {
2392
+ const o2 = n.on, s2 = o2[e2] || [], r2 = y(t2) ? t2 : [t2];
2393
+ r2.forEach((n2) => {
2262
2394
  s2.push(n2);
2263
- }), o2[e2] = s2, await G(n, e2, i2);
2395
+ }), o2[e2] = s2, await G(n, e2, r2);
2264
2396
  }
2265
2397
  function B(n, e2, t2, o2, s2) {
2266
2398
  if (!e2.on) return;
2267
- const i2 = e2.type || "unknown", r2 = n.logger.scope(i2).scope("on").scope(o2), a2 = { collector: n, logger: r2, id: t2, config: e2.config, data: s2, env: L(e2.env, e2.config.env) };
2399
+ 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) };
2268
2400
  b(e2.on)(o2, a2);
2269
2401
  }
2270
2402
  async function G(n, e2, o2, s2) {
2271
- let i2, r2 = o2 || [];
2272
- switch (o2 || (r2 = n.on[e2] || []), e2) {
2403
+ let r2, i2 = o2 || [];
2404
+ switch (o2 || (i2 = n.on[e2] || []), e2) {
2273
2405
  case t.Commands.Consent:
2274
- i2 = s2 || n.consent;
2406
+ r2 = s2 || n.consent;
2275
2407
  break;
2276
2408
  case t.Commands.Session:
2277
- i2 = n.session;
2409
+ r2 = n.session;
2278
2410
  break;
2279
2411
  case t.Commands.User:
2280
- i2 = s2 || n.user;
2412
+ r2 = s2 || n.user;
2281
2413
  break;
2282
2414
  case t.Commands.Custom:
2283
- i2 = s2 || n.custom;
2415
+ r2 = s2 || n.custom;
2284
2416
  break;
2285
2417
  case t.Commands.Globals:
2286
- i2 = s2 || n.globals;
2418
+ r2 = s2 || n.globals;
2287
2419
  break;
2288
2420
  case t.Commands.Config:
2289
- i2 = s2 || n.config;
2421
+ r2 = s2 || n.config;
2290
2422
  break;
2291
2423
  case t.Commands.Ready:
2292
2424
  case t.Commands.Run:
2293
2425
  default:
2294
- i2 = void 0;
2426
+ r2 = void 0;
2295
2427
  }
2296
2428
  let a2 = false;
2297
2429
  for (const t2 of Object.values(n.sources)) if (t2.on) {
2298
- false === await v(t2.on)(e2, i2) && (a2 = true);
2430
+ false === await v(t2.on)(e2, r2) && (a2 = true);
2299
2431
  }
2300
2432
  if (Object.entries(n.destinations).forEach(([t2, o3]) => {
2301
2433
  if (o3.on) {
2302
- if (!o3.config.init) return o3.queueOn = o3.queueOn || [], void o3.queueOn.push({ type: e2, data: i2 });
2303
- B(n, o3, t2, e2, i2);
2434
+ if (!o3.config.init) return o3.queueOn = o3.queueOn || [], void o3.queueOn.push({ type: e2, data: r2 });
2435
+ B(n, o3, t2, e2, r2);
2304
2436
  }
2305
2437
  }), (Object.keys(n.pending.sources).length > 0 || Object.keys(n.pending.destinations).length > 0) && await (async function(n2, e3) {
2306
2438
  for (const [t2, o3] of Object.entries(n2.pending.sources)) {
2307
2439
  if (!n2.pending.sources[t2] || n2.sources[t2]) continue;
2308
2440
  const s3 = o3.config?.require;
2309
2441
  if (!s3) continue;
2310
- const i3 = s3.indexOf(e3);
2311
- if (-1 === i3) continue;
2312
- if (s3.splice(i3, 1), s3.length > 0) continue;
2442
+ const r3 = s3.indexOf(e3);
2443
+ if (-1 === r3) continue;
2444
+ if (s3.splice(r3, 1), s3.length > 0) continue;
2313
2445
  delete n2.pending.sources[t2];
2314
- const r3 = await R(n2, t2, o3);
2315
- r3 && (n2.sources[t2] = r3);
2446
+ const i3 = await R(n2, t2, o3);
2447
+ i3 && (n2.sources[t2] = i3);
2316
2448
  }
2317
2449
  for (const [t2, o3] of Object.entries(n2.pending.destinations)) {
2318
2450
  if (!n2.pending.destinations[t2] || n2.destinations[t2]) continue;
2319
2451
  const s3 = o3.config?.require;
2320
2452
  if (!s3) continue;
2321
- const i3 = s3.indexOf(e3);
2322
- if (-1 === i3) continue;
2323
- if (s3.splice(i3, 1), s3.length > 0) continue;
2453
+ const r3 = s3.indexOf(e3);
2454
+ if (-1 === r3) continue;
2455
+ if (s3.splice(r3, 1), s3.length > 0) continue;
2324
2456
  delete n2.pending.destinations[t2];
2325
- const r3 = W(o3);
2326
- false !== r3.config.queue && (r3.queuePush = [...n2.queue]), n2.destinations[t2] = r3;
2457
+ const i3 = W(o3);
2458
+ false !== i3.config.queue && (i3.queuePush = [...n2.queue]), n2.destinations[t2] = i3;
2327
2459
  }
2328
- })(n, e2), !r2.length) return !a2;
2460
+ })(n, e2), !i2.length) return !a2;
2329
2461
  switch (e2) {
2330
2462
  case t.Commands.Consent:
2331
2463
  !(function(n2, e3, t2) {
@@ -2335,7 +2467,7 @@ async function G(n, e2, o2, s2) {
2335
2467
  b(e4[t3])(n2, o3);
2336
2468
  });
2337
2469
  });
2338
- })(n, r2, s2);
2470
+ })(n, i2, s2);
2339
2471
  break;
2340
2472
  case t.Commands.Ready:
2341
2473
  case t.Commands.Run:
@@ -2343,7 +2475,7 @@ async function G(n, e2, o2, s2) {
2343
2475
  n2.allowed && e3.forEach((e4) => {
2344
2476
  b(e4)(n2);
2345
2477
  });
2346
- })(n, r2);
2478
+ })(n, i2);
2347
2479
  break;
2348
2480
  case t.Commands.Session:
2349
2481
  !(function(n2, e3) {
@@ -2351,19 +2483,19 @@ async function G(n, e2, o2, s2) {
2351
2483
  e3.forEach((e4) => {
2352
2484
  b(e4)(n2, n2.session);
2353
2485
  });
2354
- })(n, r2);
2486
+ })(n, i2);
2355
2487
  break;
2356
2488
  default:
2357
- r2.forEach((e3) => {
2358
- "function" == typeof e3 && b(e3)(n, i2);
2489
+ i2.forEach((e3) => {
2490
+ "function" == typeof e3 && b(e3)(n, r2);
2359
2491
  });
2360
2492
  }
2361
2493
  return !a2;
2362
2494
  }
2363
2495
  async function H(n, e2, t2) {
2364
- const { code: o2, config: s2 = {}, env: i2 = {}, before: r2 } = e2;
2365
- if (!g(o2.push)) return N({ ok: false, failed: { invalid: { type: "invalid", error: "Destination code must have a push method" } } });
2366
- const a2 = t2 || s2 || { init: false }, c2 = r2 ? { ...a2, before: r2 } : a2, u2 = { ...o2, config: c2, env: L(o2.env, i2) };
2496
+ const { code: o2, config: s2 = {}, env: r2 = {}, before: i2 } = e2;
2497
+ if (!d(o2.push)) return N({ ok: false, failed: { invalid: { type: "invalid", error: "Destination code must have a push method" } } });
2498
+ const a2 = t2 || s2 || { init: false }, c2 = i2 ? { ...a2, before: i2 } : a2, u2 = { ...o2, config: c2, env: L(o2.env, r2) };
2367
2499
  let l2 = u2.config.id;
2368
2500
  if (!l2) do {
2369
2501
  l2 = f(4);
@@ -2371,11 +2503,11 @@ async function H(n, e2, t2) {
2371
2503
  return n.destinations[l2] = u2, false !== u2.config.queue && (u2.queuePush = [...n.queue]), U(n, void 0, {}, { [l2]: u2 });
2372
2504
  }
2373
2505
  async function U(n, e2, t2 = {}, o2) {
2374
- const { allowed: s2, consent: i2, globals: r2, user: u2 } = n;
2506
+ const { allowed: s2, consent: r2, globals: i2, user: u2 } = n;
2375
2507
  if (!s2) return N({ ok: false });
2376
2508
  e2 && (n.queue.push(e2), n.status.in++), o2 || (o2 = n.destinations);
2377
2509
  const f2 = await Promise.all(Object.entries(o2 || {}).map(async ([o3, s3]) => {
2378
- let f3 = (s3.queuePush || []).map((n2) => ({ ...n2, consent: i2 }));
2510
+ let f3 = (s3.queuePush || []).map((n2) => ({ ...n2, consent: r2 }));
2379
2511
  if (s3.queuePush = [], e2) {
2380
2512
  const n2 = c(e2);
2381
2513
  f3.push(n2);
@@ -2385,11 +2517,11 @@ async function U(n, e2, t2 = {}, o2) {
2385
2517
  const e3 = await h(F)(n, s3, o3);
2386
2518
  return { id: o3, destination: s3, skipped: !e3 };
2387
2519
  }
2388
- const d3 = [], g3 = f3.filter((n2) => {
2389
- const e3 = l(s3.config.consent, i2, n2.consent);
2390
- return !e3 || (n2.consent = e3, d3.push(n2), false);
2520
+ const g3 = [], d3 = f3.filter((n2) => {
2521
+ const e3 = l(s3.config.consent, r2, n2.consent);
2522
+ return !e3 || (n2.consent = e3, g3.push(n2), false);
2391
2523
  });
2392
- if (s3.queuePush.push(...g3), !d3.length) return { id: o3, destination: s3, queue: f3 };
2524
+ if (s3.queuePush.push(...d3), !g3.length) return { id: o3, destination: s3, queue: f3 };
2393
2525
  if (!await h(F)(n, s3, o3)) return { id: o3, destination: s3, queue: f3 };
2394
2526
  let m3, p2;
2395
2527
  s3.dlq || (s3.dlq = []);
@@ -2398,50 +2530,50 @@ async function U(n, e2, t2 = {}, o2) {
2398
2530
  return t3 ? E(t3, D(e3)) : [];
2399
2531
  })(s3, n.transformers);
2400
2532
  let y2 = 0;
2401
- return await Promise.all(d3.map(async (e3) => {
2402
- e3.globals = a(r2, e3.globals), e3.user = a(u2, e3.user);
2403
- let i3 = e3;
2533
+ return await Promise.all(g3.map(async (e3) => {
2534
+ e3.globals = a(i2, e3.globals), e3.user = a(u2, e3.user);
2535
+ let r3 = e3;
2404
2536
  if (w2.length > 0 && n.transformers && Object.keys(n.transformers).length > 0) {
2405
2537
  const o4 = await S(n, n.transformers, w2, e3, t2.ingest, t2.respond);
2406
2538
  if (null === o4) return e3;
2407
- i3 = o4;
2539
+ r3 = o4;
2408
2540
  }
2409
2541
  const c2 = Date.now(), f4 = await h(J, (e4) => {
2410
2542
  const t3 = s3.type || "unknown";
2411
- n.logger.scope(t3).error("Push failed", { error: e4, event: i3.name }), m3 = e4, s3.dlq.push([i3, e4]);
2412
- })(n, s3, o3, i3, t2.ingest, t2.respond);
2543
+ n.logger.scope(t3).error("Push failed", { error: e4, event: r3.name }), m3 = e4, s3.dlq.push([r3, e4]);
2544
+ })(n, s3, o3, r3, t2.ingest, t2.respond);
2413
2545
  return y2 += Date.now() - c2, void 0 !== f4 && (p2 = f4), e3;
2414
2546
  })), { id: o3, destination: s3, error: m3, response: p2, totalDuration: y2 };
2415
- })), d2 = {}, g2 = {}, m2 = {};
2547
+ })), g2 = {}, d2 = {}, m2 = {};
2416
2548
  for (const e3 of f2) {
2417
2549
  if (e3.skipped) continue;
2418
2550
  const t3 = e3.destination, o3 = { type: t3.type || "unknown", data: e3.response };
2419
2551
  n.status.destinations[e3.id] || (n.status.destinations[e3.id] = { count: 0, failed: 0, duration: 0 });
2420
- const s3 = n.status.destinations[e3.id], i3 = Date.now();
2421
- e3.error ? (o3.error = e3.error, m2[e3.id] = o3, s3.failed++, s3.lastAt = i3, s3.duration += e3.totalDuration || 0, n.status.failed++) : e3.queue && e3.queue.length ? (t3.queuePush = (t3.queuePush || []).concat(e3.queue), g2[e3.id] = o3) : (d2[e3.id] = o3, s3.count++, s3.lastAt = i3, s3.duration += e3.totalDuration || 0, n.status.out++);
2552
+ const s3 = n.status.destinations[e3.id], r3 = Date.now();
2553
+ e3.error ? (o3.error = e3.error, m2[e3.id] = o3, s3.failed++, s3.lastAt = r3, s3.duration += e3.totalDuration || 0, n.status.failed++) : e3.queue && e3.queue.length ? (t3.queuePush = (t3.queuePush || []).concat(e3.queue), d2[e3.id] = o3) : (g2[e3.id] = o3, s3.count++, s3.lastAt = r3, s3.duration += e3.totalDuration || 0, n.status.out++);
2422
2554
  }
2423
- return N({ event: e2, ...Object.keys(d2).length && { done: d2 }, ...Object.keys(g2).length && { queued: g2 }, ...Object.keys(m2).length && { failed: m2 } });
2555
+ return N({ event: e2, ...Object.keys(g2).length && { done: g2 }, ...Object.keys(d2).length && { queued: d2 }, ...Object.keys(m2).length && { failed: m2 } });
2424
2556
  }
2425
2557
  async function F(n, e2, t2) {
2426
2558
  if (e2.init && !e2.config.init) {
2427
- const o2 = e2.type || "unknown", s2 = n.logger.scope(o2), i2 = { collector: n, logger: s2, id: t2, config: e2.config, env: L(e2.env, e2.config.env) };
2559
+ 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) };
2428
2560
  s2.debug("init");
2429
- const r2 = await w(e2.init, "DestinationInit", n.hooks)(i2);
2430
- if (false === r2) return r2;
2431
- if (e2.config = { ...r2 || e2.config, init: true }, e2.queueOn?.length) {
2561
+ const i2 = await w(e2.init, "DestinationInit", n.hooks)(r2);
2562
+ if (false === i2) return i2;
2563
+ if (e2.config = { ...i2 || e2.config, init: true }, e2.queueOn?.length) {
2432
2564
  const o3 = e2.queueOn;
2433
2565
  e2.queueOn = [];
2434
- for (const { type: s3, data: i3 } of o3) B(n, e2, t2, s3, i3);
2566
+ for (const { type: s3, data: r3 } of o3) B(n, e2, t2, s3, r3);
2435
2567
  }
2436
2568
  s2.debug("init done");
2437
2569
  }
2438
2570
  return true;
2439
2571
  }
2440
- async function J(n, e2, t2, o2, s2, i2) {
2441
- const { config: r2 } = e2, a2 = await p(o2, r2, n);
2572
+ async function J(n, e2, t2, o2, s2, r2) {
2573
+ const { config: i2 } = e2, a2 = await p(o2, i2, n);
2442
2574
  if (a2.ignore) return false;
2443
- const c2 = e2.type || "unknown", f2 = n.logger.scope(c2), l2 = { collector: n, logger: f2, id: t2, config: r2, data: a2.data, rule: a2.mapping, ingest: s2, env: { ...L(e2.env, r2.env), ...i2 ? { respond: i2 } : {} } }, g2 = a2.mapping, m2 = a2.mappingKey || "* *";
2444
- if (!g2?.batch || !e2.pushBatch) {
2575
+ 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 || "* *";
2576
+ if (!d2?.batch || !e2.pushBatch) {
2445
2577
  f2.debug("push", { event: a2.event.name });
2446
2578
  const t3 = await w(e2.push, "DestinationPush", n.hooks)(a2.event, l2);
2447
2579
  return f2.debug("push done"), t3;
@@ -2450,12 +2582,12 @@ async function J(n, e2, t2, o2, s2, i2) {
2450
2582
  if (e2.batches = e2.batches || {}, !e2.batches[m2]) {
2451
2583
  const o4 = { key: m2, events: [], data: [] };
2452
2584
  e2.batches[m2] = { batched: o4, batchFn: u(() => {
2453
- const o5 = e2.batches[m2].batched, a3 = { collector: n, logger: f2, id: t2, config: r2, data: void 0, rule: g2, ingest: s2, env: { ...L(e2.env, r2.env), ...i2 ? { respond: i2 } : {} } };
2585
+ 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 } : {} } };
2454
2586
  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 = [];
2455
- }, g2.batch) };
2587
+ }, d2.batch) };
2456
2588
  }
2457
2589
  const o3 = e2.batches[m2];
2458
- o3.batched.events.push(a2.event), d(a2.data) && o3.batched.data.push(a2.data), o3.batchFn();
2590
+ o3.batched.events.push(a2.event), g(a2.data) && o3.batched.data.push(a2.data), o3.batchFn();
2459
2591
  }
2460
2592
  return true;
2461
2593
  }
@@ -2463,8 +2595,8 @@ function N(n) {
2463
2595
  return { ok: !n?.failed, ...n };
2464
2596
  }
2465
2597
  function W(n) {
2466
- const { code: e2, config: t2 = {}, env: o2 = {} } = n, { config: s2 } = A(n, "before"), i2 = { ...e2.config, ...t2, ...s2 }, r2 = L(e2.env, o2);
2467
- return { ...e2, config: i2, env: r2 };
2598
+ const { code: e2, config: t2 = {}, env: o2 = {} } = n, { config: s2 } = A(n, "before"), r2 = { ...e2.config, ...t2, ...s2 }, i2 = L(e2.env, o2);
2599
+ return { ...e2, config: r2, env: i2 };
2468
2600
  }
2469
2601
  async function z(n, e2 = {}) {
2470
2602
  const t2 = {};
@@ -2478,17 +2610,17 @@ async function X(n, e2, t2) {
2478
2610
  const o2 = Object.entries(n).map(async ([n2, o3]) => {
2479
2611
  const s2 = o3.destroy;
2480
2612
  if (!s2) return;
2481
- const i2 = o3.type || "unknown", r2 = t2.scope(i2), a2 = { id: n2, config: o3.config, env: o3.env ?? {}, logger: r2 };
2613
+ const r2 = o3.type || "unknown", i2 = t2.scope(r2), a2 = { id: n2, config: o3.config, env: o3.env ?? {}, logger: i2 };
2482
2614
  try {
2483
2615
  await Promise.race([s2(a2), new Promise((t3, o4) => setTimeout(() => o4(new Error(`${e2} '${n2}' destroy timed out`)), 5e3))]);
2484
2616
  } catch (t3) {
2485
- r2.error(`${e2} '${n2}' destroy failed: ${t3}`);
2617
+ i2.error(`${e2} '${n2}' destroy failed: ${t3}`);
2486
2618
  }
2487
2619
  });
2488
2620
  await Promise.allSettled(o2);
2489
2621
  }
2490
- async function Y(n, e2, o2, i2) {
2491
- let r2, a2, c2 = false, u2 = false;
2622
+ async function Y(n, e2, o2, r2) {
2623
+ let i2, a2, c2 = false, u2 = false;
2492
2624
  switch (e2) {
2493
2625
  case t.Commands.Config:
2494
2626
  K(o2) && (M(n.config, o2, { shallow: false }), a2 = o2, c2 = true);
@@ -2503,19 +2635,19 @@ async function Y(n, e2, o2, i2) {
2503
2635
  K(o2) && (n.custom = M(n.custom, o2), a2 = o2, c2 = true);
2504
2636
  break;
2505
2637
  case t.Commands.Destination:
2506
- K(o2) && ("code" in o2 && K(o2.code) ? r2 = await H(n, o2, i2) : V(o2.push) && (r2 = await H(n, { code: o2 }, i2)));
2638
+ K(o2) && ("code" in o2 && K(o2.code) ? i2 = await H(n, o2, r2) : V(o2.push) && (i2 = await H(n, { code: o2 }, r2)));
2507
2639
  break;
2508
2640
  case t.Commands.Globals:
2509
2641
  K(o2) && (n.globals = M(n.globals, o2), a2 = o2, c2 = true);
2510
2642
  break;
2511
2643
  case t.Commands.On:
2512
- _(o2) && await I(n, o2, i2);
2644
+ _(o2) && await I(n, o2, r2);
2513
2645
  break;
2514
2646
  case t.Commands.Ready:
2515
2647
  c2 = true;
2516
2648
  break;
2517
2649
  case t.Commands.Run:
2518
- r2 = await nn(n, o2), c2 = true;
2650
+ i2 = await nn(n, o2), c2 = true;
2519
2651
  break;
2520
2652
  case t.Commands.Session:
2521
2653
  c2 = true;
@@ -2523,21 +2655,21 @@ async function Y(n, e2, o2, i2) {
2523
2655
  case t.Commands.Shutdown:
2524
2656
  await (async function(n2) {
2525
2657
  const e3 = n2.logger;
2526
- await X(n2.sources, "source", e3), await X(n2.destinations, "destination", e3), await X(n2.transformers, "transformer", e3);
2658
+ await X(n2.sources, "source", e3), await X(n2.destinations, "destination", e3), await X(n2.transformers, "transformer", e3), await X(n2.stores, "store", e3);
2527
2659
  })(n);
2528
2660
  break;
2529
2661
  case t.Commands.User:
2530
2662
  K(o2) && (M(n.user, o2, { shallow: false }), a2 = o2, c2 = true);
2531
2663
  }
2532
- return c2 && await G(n, e2, void 0, a2), u2 && (r2 = await U(n)), r2 || N({ ok: true });
2664
+ return c2 && await G(n, e2, void 0, a2), u2 && (i2 = await U(n)), i2 || N({ ok: true });
2533
2665
  }
2534
2666
  function Z(n, e2) {
2535
2667
  if (!e2.name) throw new Error("Event name is required");
2536
2668
  const [t2, o2] = e2.name.split(" ");
2537
2669
  if (!t2 || !o2) throw new Error("Event name is invalid");
2538
2670
  ++n.count;
2539
- const { timestamp: s2 = Date.now(), group: i2 = n.group, count: r2 = n.count } = e2, { name: a2 = `${t2} ${o2}`, data: c2 = {}, context: u2 = {}, globals: f2 = n.globals, custom: l2 = {}, user: d2 = n.user, nested: g2 = [], consent: m2 = n.consent, id: p2 = `${s2}-${i2}-${r2}`, 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;
2540
- return { name: a2, data: c2, context: u2, globals: f2, custom: l2, user: d2, nested: g2, consent: m2, id: p2, trigger: h2, entity: w2, action: y2, timestamp: s2, timing: b2, group: i2, count: r2, version: v2, source: k2 };
2671
+ 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;
2672
+ 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 };
2541
2673
  }
2542
2674
  async function nn(n, e2) {
2543
2675
  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) => {
@@ -2547,9 +2679,9 @@ async function nn(n, e2) {
2547
2679
  }
2548
2680
  function rn(n, e2) {
2549
2681
  return sn(async (t2, o2 = {}) => await on(async () => {
2550
- const s2 = Date.now(), { id: i2, ingest: r2, respond: a2, mapping: c2, preChain: u2 } = o2;
2682
+ const s2 = Date.now(), { id: r2, ingest: i2, respond: a2, mapping: c2, preChain: u2 } = o2;
2551
2683
  let f2 = t2;
2552
- const l2 = r2 ? Object.freeze(r2) : void 0;
2684
+ const l2 = i2 ? Object.freeze(i2) : void 0;
2553
2685
  if (c2) {
2554
2686
  const e3 = await tn(f2, c2, n);
2555
2687
  if (e3.ignore) return N({ ok: true });
@@ -2563,23 +2695,30 @@ function rn(n, e2) {
2563
2695
  if (null === e3) return N({ ok: true });
2564
2696
  f2 = e3;
2565
2697
  }
2566
- const d2 = e2(f2), g2 = Z(n, d2), m2 = await U(n, g2, { id: i2, ingest: l2, respond: a2 });
2567
- if (i2) {
2568
- n.status.sources[i2] || (n.status.sources[i2] = { count: 0, duration: 0 });
2569
- const e3 = n.status.sources[i2];
2698
+ const g2 = e2(f2), d2 = Z(n, g2), m2 = await U(n, d2, { id: r2, ingest: l2, respond: a2 });
2699
+ if (r2) {
2700
+ n.status.sources[r2] || (n.status.sources[r2] = { count: 0, duration: 0 });
2701
+ const e3 = n.status.sources[r2];
2570
2702
  e3.count++, e3.lastAt = Date.now(), e3.duration += Date.now() - s2;
2571
2703
  }
2572
2704
  return m2;
2573
2705
  }, () => N({ ok: false }))(), "Push", n.hooks);
2574
2706
  }
2575
2707
  async function un(n) {
2576
- const e2 = i({ globalsStatic: {}, sessionStatic: {}, tagging: 0, run: true }, n, { merge: false, extend: false }), t2 = { level: n.logger?.level, handler: n.logger?.handler }, o2 = r(t2), s2 = { ...e2.globalsStatic, ...n.globals }, a2 = { allowed: false, config: e2, consent: n.consent || {}, count: 0, custom: n.custom || {}, destinations: {}, transformers: {}, 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.0", sources: {}, pending: { sources: {}, destinations: {} }, push: void 0, command: void 0 };
2708
+ 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 };
2577
2709
  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) {
2578
2710
  return an(async (t3, o3, s3) => await cn(async () => await e3(n2, t3, o3, s3), () => N({ ok: false }))(), "Command", n2.hooks);
2579
- })(a2, Y), a2.destinations = await z(a2, n.destinations || {}), a2.transformers = await (async function(n2, e3 = {}) {
2711
+ })(a2, Y), a2.stores = await (async function(n2, e3 = {}) {
2580
2712
  const t3 = {};
2581
2713
  for (const [o3, s3] of Object.entries(e3)) {
2582
- const { code: e4, env: i2 = {} } = s3, { config: r2 } = A(s3, "next"), a3 = n2.logger.scope("transformer").scope(o3), c2 = { collector: n2, logger: a3, id: o3, config: r2, env: i2 }, u2 = await e4(c2);
2714
+ 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);
2715
+ t3[o3] = u2;
2716
+ }
2717
+ return t3;
2718
+ })(a2, n.stores || {}), a2.destinations = await z(a2, n.destinations || {}), a2.transformers = await (async function(n2, e3 = {}) {
2719
+ const t3 = {};
2720
+ for (const [o3, s3] of Object.entries(e3)) {
2721
+ 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);
2583
2722
  t3[o3] = u2;
2584
2723
  }
2585
2724
  return t3;
@@ -2587,7 +2726,7 @@ async function un(n) {
2587
2726
  }
2588
2727
  async function fn(n) {
2589
2728
  n = n || {};
2590
- const e2 = await un(n), t2 = (o2 = e2, { type: "elb", config: {}, push: async (n2, e3, t3, s3, i3, r3) => {
2729
+ const e2 = await un(n), t2 = (o2 = e2, { type: "elb", config: {}, push: async (n2, e3, t3, s3, r3, i3) => {
2591
2730
  if ("string" == typeof n2 && n2.startsWith("walker ")) {
2592
2731
  const s4 = n2.replace("walker ", "");
2593
2732
  return o2.command(s4, e3, t3);
@@ -2598,14 +2737,14 @@ async function fn(n) {
2598
2737
  if (!n2 || "object" != typeof n2) return N({ ok: false });
2599
2738
  a3 = n2, e3 && "object" == typeof e3 && !Array.isArray(e3) && (a3.data = { ...a3.data || {}, ...e3 });
2600
2739
  }
2601
- return s3 && "object" == typeof s3 && (a3.context = s3), i3 && Array.isArray(i3) && (a3.nested = i3), r3 && "object" == typeof r3 && (a3.custom = r3), o2.push(a3);
2740
+ 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);
2602
2741
  } });
2603
2742
  var o2;
2604
2743
  e2.sources.elb = t2;
2605
2744
  const s2 = await T(e2, n.sources || {});
2606
2745
  Object.assign(e2.sources, s2);
2607
- const { consent: i2, user: r2, globals: a2, custom: c2 } = n;
2608
- i2 && await e2.command("consent", i2), r2 && await e2.command("user", r2), a2 && Object.assign(e2.globals, a2), c2 && Object.assign(e2.custom, c2), e2.config.run && await e2.command("run");
2746
+ const { consent: r2, user: i2, globals: a2, custom: c2 } = n;
2747
+ r2 && await e2.command("consent", r2), i2 && await e2.command("user", i2), a2 && Object.assign(e2.globals, a2), c2 && Object.assign(e2.custom, c2), e2.config.run && await e2.command("run");
2609
2748
  let u2 = t2.push;
2610
2749
  const f2 = Object.values(e2.sources).filter((n2) => "elb" !== n2.type), l2 = f2.find((n2) => n2.config.primary);
2611
2750
  return l2 ? u2 = l2.push : f2.length > 0 && (u2 = f2[0].push), { collector: e2, elb: u2 };
@@ -2617,58 +2756,58 @@ function ln(n) {
2617
2756
  for (const [t2, o2] of Object.entries(n)) e2[t2] = "function" == typeof o2 ? o2 : ln(o2);
2618
2757
  return e2;
2619
2758
  }
2620
- function dn(n) {
2759
+ function gn(n) {
2621
2760
  const e2 = [], { simulation: t2, ...o2 } = n, s2 = ln(o2);
2622
2761
  for (const n2 of t2) {
2623
2762
  const t3 = n2.startsWith("call:") ? n2.slice(5) : n2, o3 = t3.split(".");
2624
- let i2 = s2;
2625
- for (let n3 = 0; n3 < o3.length - 1 && null != i2[o3[n3]]; n3++) i2 = i2[o3[n3]];
2626
- const r2 = o3[o3.length - 1];
2627
- if (null == i2 || !(r2 in i2)) continue;
2628
- const a2 = i2[r2];
2629
- "function" == typeof a2 && (i2[r2] = function(...n3) {
2763
+ let r2 = s2;
2764
+ for (let n3 = 0; n3 < o3.length - 1 && null != r2[o3[n3]]; n3++) r2 = r2[o3[n3]];
2765
+ const i2 = o3[o3.length - 1];
2766
+ if (null == r2 || !(i2 in r2)) continue;
2767
+ const a2 = r2[i2];
2768
+ "function" == typeof a2 && (r2[i2] = function(...n3) {
2630
2769
  return e2.push({ fn: t3, args: n3, ts: Date.now() }), a2.apply(this, n3);
2631
2770
  });
2632
2771
  }
2633
2772
  return { wrappedEnv: s2, calls: e2 };
2634
2773
  }
2635
- async function gn(n) {
2774
+ async function dn(n) {
2636
2775
  const e2 = Date.now();
2637
2776
  try {
2638
2777
  switch (n.step) {
2639
2778
  case "transformer":
2640
2779
  return await (async function(n2, e3) {
2641
- const { code: t2, config: o2 = {}, event: s2 } = n2, { collector: i2 } = await fn({ transformers: { sim: { code: t2, config: o2 } } }), r2 = i2.transformers?.sim;
2642
- if (!r2) throw new Error("Transformer failed to initialize");
2643
- const a2 = await r2.push(s2, { collector: i2, logger: i2.logger.scope("transformer").scope("sim"), id: "sim", config: r2.config, env: r2.config?.env || {} });
2780
+ const { code: t2, config: o2 = {}, event: s2 } = n2, { collector: r2 } = await fn({ transformers: { sim: { code: t2, config: o2 } } }), i2 = r2.transformers?.sim;
2781
+ if (!i2) throw new Error("Transformer failed to initialize");
2782
+ const a2 = await i2.push(s2, { collector: r2, logger: r2.logger.scope("transformer").scope("sim"), id: "sim", config: i2.config, env: i2.config?.env || {} });
2644
2783
  let c2;
2645
2784
  c2 = false === a2 ? [] : null == a2 ? [s2] : [a2.event || s2];
2646
2785
  return { step: "transformer", name: n2.name, events: c2, calls: [], duration: Date.now() - e3 };
2647
2786
  })(n, e2);
2648
2787
  case "source":
2649
2788
  return await (async function(n2, e3) {
2650
- const { code: t2, config: o2 = {}, setup: s2, input: i2, env: r2, consent: a2 } = n2, c2 = { functional: true, marketing: true, analytics: true };
2789
+ const { code: t2, config: o2 = {}, setup: s2, input: r2, env: i2, consent: a2 } = n2, c2 = { functional: true, marketing: true, analytics: true };
2651
2790
  let u2;
2652
2791
  if (s2) {
2653
- const n3 = s2(i2, r2);
2792
+ const n3 = s2(r2, i2);
2654
2793
  "function" == typeof n3 && (u2 = n3);
2655
2794
  }
2656
- const f2 = [], { collector: l2 } = await fn({ consent: a2 || c2, sources: { sim: { code: t2, config: o2, env: r2, next: "spy" } }, transformers: { spy: { code: () => ({ type: "spy", config: {}, push: (n3) => (f2.push(JSON.parse(JSON.stringify(n3))), { event: n3 }) }) } } });
2795
+ const f2 = [], { collector: l2 } = await fn({ consent: a2 || c2, sources: { sim: { code: t2, config: o2, env: i2, next: "spy" } }, transformers: { spy: { code: () => ({ type: "spy", config: {}, push: (n3) => (f2.push(JSON.parse(JSON.stringify(n3))), { event: n3 }) }) } } });
2657
2796
  u2 && u2();
2658
2797
  return { step: "source", name: n2.name, events: f2, calls: [], duration: Date.now() - e3 };
2659
2798
  })(n, e2);
2660
2799
  case "destination":
2661
2800
  return await (async function(n2, e3) {
2662
- const { code: t2, config: o2 = {}, event: s2, consent: i2, env: r2, track: a2 } = n2, c2 = { functional: true, marketing: true, analytics: true };
2663
- let u2 = [], f2 = r2;
2664
- if (r2 && a2 && a2.length > 0) {
2665
- const n3 = dn({ ...r2, simulation: a2 });
2801
+ const { code: t2, config: o2 = {}, event: s2, consent: r2, env: i2, track: a2 } = n2, c2 = { functional: true, marketing: true, analytics: true };
2802
+ let u2 = [], f2 = i2;
2803
+ if (i2 && a2 && a2.length > 0) {
2804
+ const n3 = gn({ ...i2, simulation: a2 });
2666
2805
  f2 = n3.wrappedEnv, u2 = n3.calls;
2667
2806
  }
2668
2807
  const l2 = { ...o2 };
2669
2808
  f2 && (l2.env = f2);
2670
- const { collector: d2 } = await fn({ consent: i2 || c2, destinations: { sim: { code: t2, config: l2 } } });
2671
- return await d2.push(s2), { step: "destination", name: n2.name, events: [], calls: u2, duration: Date.now() - e3 };
2809
+ const { collector: g2 } = await fn({ consent: r2 || c2, destinations: { sim: { code: t2, config: l2 } } });
2810
+ return await g2.push(s2), { step: "destination", name: n2.name, events: [], calls: u2, duration: Date.now() - e3 };
2672
2811
  })(n, e2);
2673
2812
  }
2674
2813
  } catch (t2) {
@@ -2708,21 +2847,6 @@ async function loadDestinationEnvs(destinations) {
2708
2847
  }
2709
2848
 
2710
2849
  // src/commands/simulate/simulator.ts
2711
- function createCollectorLoggerConfigInline(logger2, verbose) {
2712
- return {
2713
- level: verbose ? Level2.DEBUG : Level2.ERROR,
2714
- handler: (level, message, context, scope) => {
2715
- const scopePath = scope.length > 0 ? `[${scope.join(":")}] ` : "";
2716
- const hasContext = Object.keys(context).length > 0;
2717
- const contextStr = hasContext ? ` ${JSON.stringify(context)}` : "";
2718
- if (level === Level2.ERROR) {
2719
- logger2.error(`${scopePath}${message}${contextStr}`);
2720
- } else {
2721
- logger2.debug(`${scopePath}${message}${contextStr}`);
2722
- }
2723
- }
2724
- };
2725
- }
2726
2850
  function callsToUsage(destName, calls) {
2727
2851
  if (!calls.length) return {};
2728
2852
  return {
@@ -2745,7 +2869,6 @@ async function simulateCore(inputPath, event, options = {}) {
2745
2869
  const result = await executeSimulation(event, inputPath, options.platform, {
2746
2870
  flow: options.flow,
2747
2871
  step: options.step,
2748
- logger: logger2,
2749
2872
  verbose: options.verbose
2750
2873
  });
2751
2874
  return result;
@@ -2800,9 +2923,8 @@ function formatSimulationResult(result, options = {}) {
2800
2923
  async function executeSimulation(event, inputPath, platformOverride, options = {}) {
2801
2924
  const startTime = Date.now();
2802
2925
  const tempDir = getTmpPath();
2803
- const collectorLoggerConfig = options.logger ? createCollectorLoggerConfigInline(options.logger, options.verbose) : void 0;
2804
2926
  try {
2805
- await fs11.ensureDir(tempDir);
2927
+ await fs12.ensureDir(tempDir);
2806
2928
  const detected = await detectInput(inputPath, platformOverride);
2807
2929
  if (!isObject(event) || !("name" in event) || typeof event.name !== "string") {
2808
2930
  throw new Error(
@@ -2821,7 +2943,6 @@ async function executeSimulation(event, inputPath, platformOverride, options = {
2821
2943
  typedEvent,
2822
2944
  tempDir,
2823
2945
  startTime,
2824
- collectorLoggerConfig,
2825
2946
  options.flow,
2826
2947
  options.step
2827
2948
  );
@@ -2834,7 +2955,7 @@ async function executeSimulation(event, inputPath, platformOverride, options = {
2834
2955
  };
2835
2956
  } finally {
2836
2957
  if (tempDir) {
2837
- await fs11.remove(tempDir).catch(() => {
2958
+ await fs12.remove(tempDir).catch(() => {
2838
2959
  });
2839
2960
  }
2840
2961
  }
@@ -2863,7 +2984,7 @@ function parseStepTarget(stepTarget, flowConfig) {
2863
2984
  }
2864
2985
  throw new Error("No destination found in flow config");
2865
2986
  }
2866
- async function executeConfigSimulation(_content, configPath, typedEvent, tempDir, startTime, loggerConfig2, flowName, stepTarget) {
2987
+ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir, startTime, flowName, stepTarget) {
2867
2988
  const { flowConfig } = await loadFlowConfig(configPath, {
2868
2989
  flowName
2869
2990
  });
@@ -2881,7 +3002,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
2881
3002
  const destinations = flowConfig.destinations;
2882
3003
  const envs = await loadDestinationEnvs(destinations || {});
2883
3004
  const destEnv = envs[step.name];
2884
- const result = await gn({
3005
+ const result = await dn({
2885
3006
  step: "destination",
2886
3007
  name: step.name,
2887
3008
  code,
@@ -2906,7 +3027,7 @@ async function executeConfigSimulation(_content, configPath, typedEvent, tempDir
2906
3027
  }
2907
3028
  const mod = await import(packageName);
2908
3029
  const code = mod.default || Object.values(mod)[0];
2909
- const result = await gn({
3030
+ const result = await dn({
2910
3031
  step: "transformer",
2911
3032
  name: step.name,
2912
3033
  code,
@@ -2978,7 +3099,7 @@ async function simulateSourceCLI(flowConfig, setupInput, options) {
2978
3099
  document: dom.window.document,
2979
3100
  localStorage: dom.window.localStorage
2980
3101
  };
2981
- const result = await gn({
3102
+ const result = await dn({
2982
3103
  step: "source",
2983
3104
  name: options.sourceStep,
2984
3105
  code,
@@ -3116,129 +3237,33 @@ async function simulateCommand(options) {
3116
3237
  let config;
3117
3238
  if (isStdinPiped() && !options.config) {
3118
3239
  const stdinContent = await readStdin();
3119
- const fs14 = await import("fs-extra");
3120
- const path14 = await import("path");
3240
+ const fs15 = await import("fs-extra");
3241
+ const path15 = await import("path");
3121
3242
  const tmpPath = getTmpPath(void 0, "stdin-simulate.json");
3122
- await fs14.default.ensureDir(path14.default.dirname(tmpPath));
3123
- await fs14.default.writeFile(tmpPath, stdinContent, "utf-8");
3243
+ await fs15.default.ensureDir(path15.default.dirname(tmpPath));
3244
+ await fs15.default.writeFile(tmpPath, stdinContent, "utf-8");
3124
3245
  config = tmpPath;
3125
3246
  } else {
3126
3247
  config = options.config || "bundle.config.json";
3127
3248
  }
3128
- let event;
3129
- let exampleContext;
3130
- if (options.example) {
3131
- const rawConfig = await loadJsonConfig(config);
3132
- const setup = validateFlowSetup(rawConfig);
3133
- const flowNames = Object.keys(setup.flows);
3134
- let flowName = options.flow;
3135
- if (!flowName) {
3136
- if (flowNames.length === 1) {
3137
- flowName = flowNames[0];
3138
- } else {
3139
- throw new Error(
3140
- `Multiple flows found. Use --flow to specify which flow contains the example.
3141
- Available flows: ${flowNames.join(", ")}`
3142
- );
3143
- }
3144
- }
3145
- const flowConfig = setup.flows[flowName];
3146
- if (!flowConfig) {
3147
- throw new Error(
3148
- `Flow "${flowName}" not found. Available: ${flowNames.join(", ")}`
3149
- );
3150
- }
3151
- const found = findExample(flowConfig, options.example, options.step);
3152
- if (found.example.in === void 0) {
3153
- throw new Error(
3154
- `Example "${options.example}" in ${found.stepType}.${found.stepName} has no "in" value`
3155
- );
3156
- }
3157
- event = found.example.in;
3158
- exampleContext = {
3159
- stepType: found.stepType,
3160
- stepName: found.stepName,
3161
- expected: found.example.out
3162
- };
3163
- } else {
3164
- event = await loadJsonFromSource(options.event, {
3165
- name: "event"
3166
- });
3167
- }
3168
- const isSourceSimulation = exampleContext?.stepType === "source" || options.step?.startsWith("source.");
3169
- let result;
3170
- if (isSourceSimulation) {
3171
- const rawConfig = await loadJsonConfig(config);
3172
- const setup = validateFlowSetup(rawConfig);
3173
- const flowNames = Object.keys(setup.flows);
3174
- const flowName = options.flow || (flowNames.length === 1 ? flowNames[0] : void 0);
3175
- if (!flowName) {
3176
- throw new Error(
3177
- `Multiple flows found. Use --flow to specify which flow.
3178
- Available: ${flowNames.join(", ")}`
3179
- );
3180
- }
3181
- const flowConfig = setup.flows[flowName];
3182
- if (!flowConfig) {
3183
- throw new Error(
3184
- `Flow "${flowName}" not found. Available: ${flowNames.join(", ")}`
3185
- );
3186
- }
3187
- const sourceStep = exampleContext?.stepName || options.step.substring("source.".length);
3188
- result = await simulateSourceCLI(
3189
- flowConfig,
3190
- event,
3191
- {
3192
- flow: options.flow,
3193
- sourceStep,
3194
- json: options.json,
3195
- verbose: options.verbose,
3196
- silent: options.silent
3197
- }
3198
- );
3199
- } else {
3200
- const stepTarget = exampleContext ? `${exampleContext.stepType}.${exampleContext.stepName}` : options.step;
3201
- result = await simulateCore(config, event, {
3202
- flow: options.flow,
3203
- json: options.json,
3204
- verbose: options.verbose,
3205
- silent: options.silent,
3206
- step: stepTarget
3207
- });
3208
- }
3209
- let exampleMatch;
3210
- if (exampleContext && result.success) {
3211
- const stepKey = `${exampleContext.stepType}.${exampleContext.stepName}`;
3212
- if (exampleContext.expected === false) {
3213
- const calls = result.usage?.[exampleContext.stepName];
3214
- const wasFiltered = !calls || calls.length === 0;
3215
- exampleMatch = {
3216
- name: options.example,
3217
- step: stepKey,
3218
- expected: false,
3219
- actual: wasFiltered ? false : calls,
3220
- match: wasFiltered,
3221
- diff: wasFiltered ? void 0 : `Expected event to be filtered, but ${calls.length} API call(s) were made`
3222
- };
3223
- } else if (exampleContext.expected !== void 0) {
3224
- const actual = result.usage?.[exampleContext.stepName] ?? [];
3225
- exampleMatch = {
3226
- name: options.example,
3227
- step: stepKey,
3228
- ...compareOutput(exampleContext.expected, actual)
3229
- };
3230
- }
3231
- }
3249
+ const result = await simulate(config, options.event, {
3250
+ flow: options.flow,
3251
+ json: options.json,
3252
+ verbose: options.verbose,
3253
+ silent: options.silent,
3254
+ platform: options.platform,
3255
+ example: options.example,
3256
+ step: options.step
3257
+ });
3232
3258
  const resultWithDuration = {
3233
3259
  ...result,
3234
- duration: (Date.now() - startTime) / 1e3,
3235
- ...exampleMatch ? { exampleMatch } : {}
3260
+ duration: (Date.now() - startTime) / 1e3
3236
3261
  };
3237
3262
  const formatted = formatSimulationResult(resultWithDuration, {
3238
3263
  json: options.json
3239
3264
  });
3240
3265
  await writeResult(formatted + "\n", { output: options.output });
3241
- const exitCode = !result.success || exampleMatch && !exampleMatch.match ? 1 : 0;
3266
+ const exitCode = !result.success || result.exampleMatch && !result.exampleMatch.match ? 1 : 0;
3242
3267
  process.exit(exitCode);
3243
3268
  } catch (error) {
3244
3269
  const errorMessage = getErrorMessage(error);
@@ -3266,6 +3291,9 @@ async function simulate(configOrPath, event, options = {}) {
3266
3291
  );
3267
3292
  }
3268
3293
  let resolvedEvent = event;
3294
+ if (typeof event === "string") {
3295
+ resolvedEvent = await loadJsonFromSource(event, { name: "event" });
3296
+ }
3269
3297
  let exampleContext;
3270
3298
  if (options.example) {
3271
3299
  const rawConfig = await loadJsonConfig(configOrPath);
@@ -3301,12 +3329,48 @@ Available flows: ${flowNames.join(", ")}`
3301
3329
  expected: found.example.out
3302
3330
  };
3303
3331
  }
3304
- const result = await simulateCore(configOrPath, resolvedEvent, {
3305
- json: options.json ?? false,
3306
- verbose: options.verbose ?? false,
3307
- flow: options.flow,
3308
- platform: options.platform
3309
- });
3332
+ const isSourceSimulation = exampleContext?.stepType === "source" || options.step?.startsWith("source.");
3333
+ let result;
3334
+ if (isSourceSimulation) {
3335
+ const rawConfig = await loadJsonConfig(configOrPath);
3336
+ const setup = validateFlowSetup(rawConfig);
3337
+ const flowNames = Object.keys(setup.flows);
3338
+ const flowName = options.flow || (flowNames.length === 1 ? flowNames[0] : void 0);
3339
+ if (!flowName) {
3340
+ throw new Error(
3341
+ `Multiple flows found. Use --flow to specify which flow.
3342
+ Available: ${flowNames.join(", ")}`
3343
+ );
3344
+ }
3345
+ const flowConfig = setup.flows[flowName];
3346
+ if (!flowConfig) {
3347
+ throw new Error(
3348
+ `Flow "${flowName}" not found. Available: ${flowNames.join(", ")}`
3349
+ );
3350
+ }
3351
+ const sourceStep = exampleContext?.stepName || options.step.substring("source.".length);
3352
+ result = await simulateSourceCLI(
3353
+ flowConfig,
3354
+ resolvedEvent,
3355
+ {
3356
+ flow: options.flow,
3357
+ sourceStep,
3358
+ json: options.json,
3359
+ verbose: options.verbose,
3360
+ silent: options.silent
3361
+ }
3362
+ );
3363
+ } else {
3364
+ const stepTarget = exampleContext ? `${exampleContext.stepType}.${exampleContext.stepName}` : options.step;
3365
+ result = await simulateCore(configOrPath, resolvedEvent, {
3366
+ json: options.json ?? false,
3367
+ verbose: options.verbose ?? false,
3368
+ silent: options.silent ?? false,
3369
+ flow: options.flow,
3370
+ platform: options.platform,
3371
+ step: stepTarget
3372
+ });
3373
+ }
3310
3374
  if (exampleContext && result.success) {
3311
3375
  const stepKey = `${exampleContext.stepType}.${exampleContext.stepName}`;
3312
3376
  if (exampleContext.expected === false) {
@@ -3334,27 +3398,12 @@ Available flows: ${flowNames.join(", ")}`
3334
3398
 
3335
3399
  // src/commands/push/index.ts
3336
3400
  init_cli_logger();
3337
- import path11 from "path";
3401
+ import path12 from "path";
3338
3402
  import { JSDOM as JSDOM2, VirtualConsole as VirtualConsole2 } from "jsdom";
3339
- import fs12 from "fs-extra";
3403
+ import fs13 from "fs-extra";
3340
3404
  import { getPlatform as getPlatform3 } from "@walkeros/core";
3341
3405
  import { schemas as schemas2 } from "@walkeros/core/dev";
3342
- import { Level as Level3 } from "@walkeros/core";
3343
- function createCollectorLoggerConfig(logger2, verbose) {
3344
- return {
3345
- level: verbose ? Level3.DEBUG : Level3.ERROR,
3346
- handler: (level, message, context, scope) => {
3347
- const scopePath = scope.length > 0 ? `[${scope.join(":")}] ` : "";
3348
- const hasContext = Object.keys(context).length > 0;
3349
- const contextStr = hasContext ? ` ${JSON.stringify(context)}` : "";
3350
- if (level === Level3.ERROR) {
3351
- logger2.error(`${scopePath}${message}${contextStr}`);
3352
- } else {
3353
- logger2.debug(`${scopePath}${message}${contextStr}`);
3354
- }
3355
- }
3356
- };
3357
- }
3406
+ import { Level as Level2 } from "@walkeros/core";
3358
3407
  async function pushCore(inputPath, event, options = {}) {
3359
3408
  const logger2 = createCLILogger({
3360
3409
  silent: options.silent,
@@ -3363,11 +3412,7 @@ async function pushCore(inputPath, event, options = {}) {
3363
3412
  const startTime = Date.now();
3364
3413
  let tempDir;
3365
3414
  try {
3366
- let loadedEvent = event;
3367
- if (typeof event === "string") {
3368
- loadedEvent = await loadJsonFromSource(event, { name: "event" });
3369
- }
3370
- const eventResult = schemas2.PartialEventSchema.safeParse(loadedEvent);
3415
+ const eventResult = schemas2.PartialEventSchema.safeParse(event);
3371
3416
  if (!eventResult.success) {
3372
3417
  const errors = eventResult.error.issues.map((issue) => `${String(issue.path.join("."))}: ${issue.message}`).join(", ");
3373
3418
  throw new Error(`Invalid event: ${errors}`);
@@ -3413,7 +3458,7 @@ async function pushCore(inputPath, event, options = {}) {
3413
3458
  (dir) => {
3414
3459
  tempDir = dir;
3415
3460
  },
3416
- { logger: createCollectorLoggerConfig(logger2, options.verbose) }
3461
+ { logger: { level: options.verbose ? Level2.DEBUG : Level2.ERROR } }
3417
3462
  );
3418
3463
  }
3419
3464
  return result;
@@ -3425,7 +3470,7 @@ async function pushCore(inputPath, event, options = {}) {
3425
3470
  };
3426
3471
  } finally {
3427
3472
  if (tempDir) {
3428
- await fs12.remove(tempDir).catch(() => {
3473
+ await fs13.remove(tempDir).catch(() => {
3429
3474
  });
3430
3475
  }
3431
3476
  }
@@ -3438,14 +3483,13 @@ async function pushCommand(options) {
3438
3483
  if (isStdinPiped() && !options.config) {
3439
3484
  const stdinContent = await readStdin();
3440
3485
  const tmpPath = getTmpPath(void 0, "stdin-push.json");
3441
- await fs12.ensureDir(path11.dirname(tmpPath));
3442
- await fs12.writeFile(tmpPath, stdinContent, "utf-8");
3486
+ await fs13.ensureDir(path12.dirname(tmpPath));
3487
+ await fs13.writeFile(tmpPath, stdinContent, "utf-8");
3443
3488
  config = tmpPath;
3444
3489
  } else {
3445
3490
  config = options.config || "bundle.config.json";
3446
3491
  }
3447
- const event = await loadJsonFromSource(options.event, { name: "event" });
3448
- const result = await pushCore(config, event, {
3492
+ const result = await push(config, options.event, {
3449
3493
  flow: options.flow,
3450
3494
  json: options.json,
3451
3495
  verbose: options.verbose,
@@ -3507,9 +3551,14 @@ async function push(configOrPath, event, options = {}) {
3507
3551
  "push() currently only supports config file paths. Config object support will be added in a future version. Please provide a path to a configuration file."
3508
3552
  );
3509
3553
  }
3510
- return await pushCore(configOrPath, event, {
3554
+ let resolvedEvent = event;
3555
+ if (typeof event === "string") {
3556
+ resolvedEvent = await loadJsonFromSource(event, { name: "event" });
3557
+ }
3558
+ return await pushCore(configOrPath, resolvedEvent, {
3511
3559
  json: options.json ?? false,
3512
3560
  verbose: options.verbose ?? false,
3561
+ silent: options.silent ?? false,
3513
3562
  flow: options.flow,
3514
3563
  platform: options.platform
3515
3564
  });
@@ -3528,8 +3577,8 @@ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
3528
3577
  `push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
3529
3578
  );
3530
3579
  setTempDir(tempDir);
3531
- await fs12.ensureDir(tempDir);
3532
- const tempPath = path11.join(
3580
+ await fs13.ensureDir(tempDir);
3581
+ const tempPath = path12.join(
3533
3582
  tempDir,
3534
3583
  `bundle.${platform === "web" ? "js" : "mjs"}`
3535
3584
  );
@@ -3551,7 +3600,7 @@ async function executeConfigPush(options, validatedEvent, logger2, setTempDir) {
3551
3600
  } else if (platform === "server") {
3552
3601
  logger2.debug("Executing in server environment (Node.js)");
3553
3602
  return executeServerPush(tempPath, validatedEvent, logger2, 6e4, {
3554
- logger: createCollectorLoggerConfig(logger2, options.verbose)
3603
+ logger: { level: options.verbose ? Level2.DEBUG : Level2.ERROR }
3555
3604
  });
3556
3605
  } else {
3557
3606
  throw new Error(`Unsupported platform: ${platform}`);
@@ -3563,12 +3612,12 @@ async function executeBundlePush(bundleContent, platform, validatedEvent, logger
3563
3612
  `push-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
3564
3613
  );
3565
3614
  setTempDir(tempDir);
3566
- await fs12.ensureDir(tempDir);
3567
- const tempPath = path11.join(
3615
+ await fs13.ensureDir(tempDir);
3616
+ const tempPath = path12.join(
3568
3617
  tempDir,
3569
3618
  `bundle.${platform === "server" ? "mjs" : "js"}`
3570
3619
  );
3571
- await fs12.writeFile(tempPath, bundleContent, "utf8");
3620
+ await fs13.writeFile(tempPath, bundleContent, "utf8");
3572
3621
  logger2.debug(`Bundle written to: ${tempPath}`);
3573
3622
  if (platform === "web") {
3574
3623
  logger2.debug("Executing in web environment (JSDOM)");
@@ -3590,7 +3639,7 @@ async function executeWebPush(bundlePath, event, logger2) {
3590
3639
  });
3591
3640
  const { window } = dom;
3592
3641
  logger2.debug("Loading bundle...");
3593
- const bundleCode = await fs12.readFile(bundlePath, "utf8");
3642
+ const bundleCode = await fs13.readFile(bundlePath, "utf8");
3594
3643
  window.eval(bundleCode);
3595
3644
  logger2.debug("Waiting for collector...");
3596
3645
  await waitForWindowProperty(
@@ -3686,7 +3735,8 @@ function waitForWindowProperty(window, prop, timeout = 5e3) {
3686
3735
 
3687
3736
  // src/commands/run/index.ts
3688
3737
  init_cli_logger();
3689
- import path13 from "path";
3738
+ import path14 from "path";
3739
+ import { createRequire } from "module";
3690
3740
 
3691
3741
  // src/commands/run/validators.ts
3692
3742
  import { existsSync as existsSync3 } from "fs";
@@ -3805,15 +3855,15 @@ function validatePort(port) {
3805
3855
  }
3806
3856
 
3807
3857
  // src/commands/run/utils.ts
3808
- import path12 from "path";
3809
- import fs13 from "fs-extra";
3858
+ import path13 from "path";
3859
+ import fs14 from "fs-extra";
3810
3860
  async function prepareBundleForRun(configPath, options) {
3811
3861
  const tempDir = getTmpPath(
3812
3862
  void 0,
3813
3863
  `run-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`
3814
3864
  );
3815
- await fs13.ensureDir(tempDir);
3816
- const tempPath = path12.join(tempDir, "bundle.mjs");
3865
+ await fs14.ensureDir(tempDir);
3866
+ const tempPath = path13.join(tempDir, "bundle.mjs");
3817
3867
  await bundle(configPath, {
3818
3868
  cache: true,
3819
3869
  verbose: options.verbose,
@@ -3832,7 +3882,7 @@ function isPreBuiltConfig(configPath) {
3832
3882
  }
3833
3883
 
3834
3884
  // src/commands/run/execution.ts
3835
- import { createLogger as createLogger2, Level as Level4 } from "@walkeros/core";
3885
+ import { createLogger as createLogger2, Level as Level3 } from "@walkeros/core";
3836
3886
 
3837
3887
  // src/runtime/runner.ts
3838
3888
  import { pathToFileURL } from "url";
@@ -3917,7 +3967,7 @@ import { randomBytes } from "crypto";
3917
3967
  var instanceId = randomBytes(8).toString("hex");
3918
3968
 
3919
3969
  // src/commands/run/execution.ts
3920
- var logLevel = process.env.VERBOSE === "true" ? Level4.DEBUG : Level4.INFO;
3970
+ var logLevel = process.env.VERBOSE === "true" ? Level3.DEBUG : Level3.INFO;
3921
3971
  var loggerConfig = { level: logLevel };
3922
3972
  var logger = createLogger2(loggerConfig);
3923
3973
  async function executeRunLocal(flowPath, options) {
@@ -3929,6 +3979,7 @@ async function executeRunLocal(flowPath, options) {
3929
3979
  }
3930
3980
 
3931
3981
  // src/commands/run/index.ts
3982
+ var esmRequire = createRequire(import.meta.url);
3932
3983
  async function runCommand(options) {
3933
3984
  const timer = createTimer();
3934
3985
  timer.start();
@@ -3941,7 +3992,7 @@ async function runCommand(options) {
3941
3992
  const runtimeDeps = ["express", "cors"];
3942
3993
  for (const dep of runtimeDeps) {
3943
3994
  try {
3944
- __require.resolve(dep);
3995
+ esmRequire.resolve(dep);
3945
3996
  } catch {
3946
3997
  logger2.error(
3947
3998
  `Missing runtime dependency "${dep}"
@@ -3954,8 +4005,8 @@ Run: npm install express cors`
3954
4005
  const isPreBuilt = isPreBuiltConfig(configPath);
3955
4006
  let flowPath;
3956
4007
  if (isPreBuilt) {
3957
- flowPath = path13.resolve(configPath);
3958
- logger2.debug(`Using pre-built flow: ${path13.basename(flowPath)}`);
4008
+ flowPath = path14.resolve(configPath);
4009
+ logger2.debug(`Using pre-built flow: ${path14.basename(flowPath)}`);
3959
4010
  } else {
3960
4011
  logger2.debug("Building flow bundle");
3961
4012
  flowPath = await prepareBundleForRun(configPath, {
@@ -4009,7 +4060,7 @@ async function run(options) {
4009
4060
  const runtimeDeps = ["express", "cors"];
4010
4061
  for (const dep of runtimeDeps) {
4011
4062
  try {
4012
- __require.resolve(dep);
4063
+ esmRequire.resolve(dep);
4013
4064
  } catch {
4014
4065
  throw new Error(
4015
4066
  `Missing runtime dependency "${dep}". Server flows require express and cors when running outside Docker. Run: npm install express cors`
@@ -4019,7 +4070,7 @@ async function run(options) {
4019
4070
  const isPreBuilt = isPreBuiltConfig(flowFile);
4020
4071
  let flowPath;
4021
4072
  if (isPreBuilt) {
4022
- flowPath = path13.resolve(flowFile);
4073
+ flowPath = path14.resolve(flowFile);
4023
4074
  } else {
4024
4075
  flowPath = await prepareBundleForRun(flowFile, {
4025
4076
  verbose: options.verbose,
@@ -4174,10 +4225,10 @@ function validateEvent(input) {
4174
4225
  const zodResult = PartialEventSchema.safeParse(input);
4175
4226
  if (!zodResult.success) {
4176
4227
  for (const issue of zodResult.error.issues) {
4177
- const path14 = issue.path.join(".");
4178
- if (path14 === "name") continue;
4228
+ const path15 = issue.path.join(".");
4229
+ if (path15 === "name") continue;
4179
4230
  errors.push({
4180
- path: path14 || "root",
4231
+ path: path15 || "root",
4181
4232
  message: issue.message,
4182
4233
  code: "SCHEMA_VALIDATION"
4183
4234
  });
@@ -4390,10 +4441,10 @@ function buildConnectionGraph(config) {
4390
4441
  function checkCompatibility(conn, errors, warnings) {
4391
4442
  const fromOuts = Object.entries(conn.from.examples).filter(([, ex]) => ex.out !== void 0 && ex.out !== false).map(([name, ex]) => ({ name, value: ex.out }));
4392
4443
  const toIns = Object.entries(conn.to.examples).filter(([, ex]) => ex.in !== void 0).map(([name, ex]) => ({ name, value: ex.in }));
4393
- const path14 = `${conn.from.type}.${conn.from.name} \u2192 ${conn.to.type}.${conn.to.name}`;
4444
+ const path15 = `${conn.from.type}.${conn.from.name} \u2192 ${conn.to.type}.${conn.to.name}`;
4394
4445
  if (fromOuts.length === 0 || toIns.length === 0) {
4395
4446
  warnings.push({
4396
- path: path14,
4447
+ path: path15,
4397
4448
  message: "Cannot check compatibility: missing out or in examples",
4398
4449
  suggestion: "Add out examples to the source step or in examples to the target step"
4399
4450
  });
@@ -4411,7 +4462,7 @@ function checkCompatibility(conn, errors, warnings) {
4411
4462
  }
4412
4463
  if (!hasMatch) {
4413
4464
  errors.push({
4414
- path: path14,
4465
+ path: path15,
4415
4466
  message: "No compatible out/in pair found between connected steps",
4416
4467
  code: "INCOMPATIBLE_EXAMPLES"
4417
4468
  });
@@ -4507,13 +4558,13 @@ function validateMapping(input) {
4507
4558
  import Ajv from "ajv";
4508
4559
  import { fetchPackageSchema } from "@walkeros/core";
4509
4560
  var SECTIONS = ["destinations", "sources", "transformers"];
4510
- function resolveEntry(path14, flowConfig) {
4561
+ function resolveEntry(path15, flowConfig) {
4511
4562
  const flows = flowConfig.flows;
4512
4563
  if (!flows || typeof flows !== "object") return "No flows found in config";
4513
4564
  const flowName = Object.keys(flows)[0];
4514
4565
  const flow = flows[flowName];
4515
4566
  if (!flow) return `Flow "${flowName}" is empty`;
4516
- const parts = path14.split(".");
4567
+ const parts = path15.split(".");
4517
4568
  if (parts.length === 2) {
4518
4569
  const [section, key] = parts;
4519
4570
  if (!SECTIONS.includes(section)) {
@@ -4550,15 +4601,15 @@ function resolveEntry(path14, flowConfig) {
4550
4601
  }
4551
4602
  return { section: matches[0].section, key, entry: matches[0].entry };
4552
4603
  }
4553
- return `Invalid path "${path14}". Use "section.key" or just "key"`;
4604
+ return `Invalid path "${path15}". Use "section.key" or just "key"`;
4554
4605
  }
4555
- async function validateEntry(path14, flowConfig) {
4556
- const resolved = resolveEntry(path14, flowConfig);
4606
+ async function validateEntry(path15, flowConfig) {
4607
+ const resolved = resolveEntry(path15, flowConfig);
4557
4608
  if (typeof resolved === "string") {
4558
4609
  return {
4559
4610
  valid: false,
4560
4611
  type: "entry",
4561
- errors: [{ path: path14, message: resolved, code: "ENTRY_VALIDATION" }],
4612
+ errors: [{ path: path15, message: resolved, code: "ENTRY_VALIDATION" }],
4562
4613
  warnings: [],
4563
4614
  details: {}
4564
4615
  };
@@ -4589,7 +4640,7 @@ async function validateEntry(path14, flowConfig) {
4589
4640
  type: "entry",
4590
4641
  errors: [
4591
4642
  {
4592
- path: path14,
4643
+ path: path15,
4593
4644
  message: error instanceof Error ? error.message : "Unknown error",
4594
4645
  code: "ENTRY_VALIDATION"
4595
4646
  }
@@ -4638,18 +4689,25 @@ async function validateEntry(path14, flowConfig) {
4638
4689
 
4639
4690
  // src/commands/validate/index.ts
4640
4691
  async function validate(type, input, options = {}) {
4692
+ let resolved = input;
4693
+ if (typeof input === "string") {
4694
+ resolved = await loadJsonFromSource(input, {
4695
+ name: type,
4696
+ required: true
4697
+ });
4698
+ }
4641
4699
  if (options.path) {
4642
- return validateEntry(options.path, input);
4700
+ return validateEntry(options.path, resolved);
4643
4701
  }
4644
4702
  switch (type) {
4645
4703
  case "contract":
4646
- return validateContract(input);
4704
+ return validateContract(resolved);
4647
4705
  case "event":
4648
- return validateEvent(input);
4706
+ return validateEvent(resolved);
4649
4707
  case "flow":
4650
- return validateFlow(input, { flow: options.flow });
4708
+ return validateFlow(resolved, { flow: options.flow });
4651
4709
  case "mapping":
4652
- return validateMapping(input);
4710
+ return validateMapping(resolved);
4653
4711
  default:
4654
4712
  throw new Error(`Unknown validation type: ${type}`);
4655
4713
  }
@@ -4700,10 +4758,7 @@ async function validateCommand(options) {
4700
4758
  throw new Error("Invalid JSON received on stdin");
4701
4759
  }
4702
4760
  } else {
4703
- input = await loadJsonFromSource(options.input, {
4704
- name: options.type,
4705
- required: true
4706
- });
4761
+ input = options.input;
4707
4762
  }
4708
4763
  const result = await validate(options.type, input, {
4709
4764
  flow: options.flow,
@@ -4996,7 +5051,10 @@ async function getFlow(options) {
4996
5051
  const { data, error } = await client.GET(
4997
5052
  "/api/projects/{projectId}/flows/{flowId}",
4998
5053
  {
4999
- params: { path: { projectId: id, flowId: options.flowId } }
5054
+ params: {
5055
+ path: { projectId: id, flowId: options.flowId },
5056
+ query: options.fields ? { fields: options.fields.join(",") } : {}
5057
+ }
5000
5058
  }
5001
5059
  );
5002
5060
  if (error) throw new Error(error.error?.message || "Failed to get flow");
@@ -5024,7 +5082,10 @@ async function updateFlow(options) {
5024
5082
  {
5025
5083
  params: { path: { projectId: id, flowId: options.flowId } },
5026
5084
  // Dynamically constructed body; server validates the full schema
5027
- body
5085
+ body,
5086
+ ...options.mergePatch && {
5087
+ headers: { "Content-Type": "application/merge-patch+json" }
5088
+ }
5028
5089
  }
5029
5090
  );
5030
5091
  if (error) throw new Error(error.error?.message || "Failed to update flow");