@walkeros/cli 4.1.0-next-1778668930820 → 4.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1897,8 +1897,8 @@ import fs11 from "fs-extra";
1897
1897
  import {
1898
1898
  packageNameToVariable,
1899
1899
  ENV_MARKER_PREFIX,
1900
- validateTransformerEntry,
1901
- isPathTransformerEntry
1900
+ validateStepEntry,
1901
+ isPathStepEntry
1902
1902
  } from "@walkeros/core";
1903
1903
  import { getHashServer as getHashServer3 } from "@walkeros/server-core";
1904
1904
  function isInlineCode(code) {
@@ -1921,7 +1921,7 @@ function hasCodeReference(code) {
1921
1921
  }
1922
1922
  function validateReference(type, name, ref) {
1923
1923
  if (type === "Transformer") {
1924
- const r = validateTransformerEntry({ ...ref });
1924
+ const r = validateStepEntry({ ...ref }, "Transformer");
1925
1925
  if (!r.ok) {
1926
1926
  throw new Error(`Transformer "${name}": ${r.reason ?? "invalid entry."}`);
1927
1927
  }
@@ -2034,8 +2034,7 @@ async function bundleCore(flowSettings, buildOptions, logger, showStats = false)
2034
2034
  const varName = packageNameToVariable(pkg);
2035
2035
  if (!buildOptions.packages[varName]) {
2036
2036
  buildOptions.packages[varName] = {
2037
- path: pkg,
2038
- imports: [`default as ${varName}`]
2037
+ path: pkg
2039
2038
  };
2040
2039
  }
2041
2040
  for (const section of [
@@ -2048,8 +2047,7 @@ async function bundleCore(flowSettings, buildOptions, logger, showStats = false)
2048
2047
  if (!steps) continue;
2049
2048
  for (const step of Object.values(steps)) {
2050
2049
  if (step.package === pkg) {
2051
- step.code = varName;
2052
- delete step.package;
2050
+ step.package = varName;
2053
2051
  }
2054
2052
  }
2055
2053
  }
@@ -2502,67 +2500,27 @@ function collectAllStepPackages(flowSettings) {
2502
2500
  }
2503
2501
  return allPackages;
2504
2502
  }
2505
- function detectExplicitCodeImports(flowSettings) {
2506
- const explicitCodeImports = /* @__PURE__ */ new Map();
2507
- const destinations = flowSettings.destinations;
2508
- if (destinations) {
2509
- for (const [, destConfig] of Object.entries(destinations)) {
2510
- if (typeof destConfig.package === "string" && typeof destConfig.code === "string") {
2511
- const isAutoGenerated = destConfig.code.startsWith("_");
2512
- if (!isAutoGenerated) {
2513
- if (!explicitCodeImports.has(destConfig.package)) {
2514
- explicitCodeImports.set(destConfig.package, /* @__PURE__ */ new Set());
2515
- }
2516
- explicitCodeImports.get(destConfig.package).add(destConfig.code);
2517
- }
2518
- }
2519
- }
2520
- }
2521
- const sources = flowSettings.sources;
2522
- if (sources) {
2523
- for (const [, sourceConfig] of Object.entries(sources)) {
2524
- if (typeof sourceConfig.package === "string" && typeof sourceConfig.code === "string") {
2525
- const isAutoGenerated = sourceConfig.code.startsWith("_");
2526
- if (!isAutoGenerated) {
2527
- if (!explicitCodeImports.has(sourceConfig.package)) {
2528
- explicitCodeImports.set(sourceConfig.package, /* @__PURE__ */ new Set());
2529
- }
2530
- explicitCodeImports.get(sourceConfig.package).add(sourceConfig.code);
2531
- }
2532
- }
2533
- }
2534
- }
2535
- const transformers = flowSettings.transformers;
2536
- if (transformers) {
2537
- for (const [, transformerConfig] of Object.entries(transformers)) {
2538
- if (typeof transformerConfig.package === "string" && typeof transformerConfig.code === "string") {
2539
- const isAutoGenerated = transformerConfig.code.startsWith("_");
2540
- if (!isAutoGenerated) {
2541
- if (!explicitCodeImports.has(transformerConfig.package)) {
2542
- explicitCodeImports.set(transformerConfig.package, /* @__PURE__ */ new Set());
2543
- }
2544
- explicitCodeImports.get(transformerConfig.package).add(transformerConfig.code);
2545
- }
2546
- }
2547
- }
2548
- }
2549
- const stores = flowSettings.stores;
2550
- if (stores) {
2551
- for (const [, storeConfig] of Object.entries(stores)) {
2552
- if (typeof storeConfig.package === "string" && typeof storeConfig.code === "string") {
2553
- const isAutoGenerated = storeConfig.code.startsWith("_");
2554
- if (!isAutoGenerated) {
2555
- if (!explicitCodeImports.has(storeConfig.package)) {
2556
- explicitCodeImports.set(storeConfig.package, /* @__PURE__ */ new Set());
2557
- }
2558
- explicitCodeImports.get(storeConfig.package).add(storeConfig.code);
2559
- }
2503
+ function detectNamedImports(flowSettings) {
2504
+ const namedImports = /* @__PURE__ */ new Map();
2505
+ const addNamed = (pkg, importName) => {
2506
+ if (!namedImports.has(pkg)) namedImports.set(pkg, /* @__PURE__ */ new Set());
2507
+ namedImports.get(pkg).add(importName);
2508
+ };
2509
+ const visit = (bucket) => {
2510
+ if (!bucket) return;
2511
+ for (const step of Object.values(bucket)) {
2512
+ if (typeof step.package === "string" && typeof step.import === "string") {
2513
+ addNamed(step.package, step.import);
2560
2514
  }
2561
2515
  }
2562
- }
2563
- return explicitCodeImports;
2516
+ };
2517
+ visit(flowSettings.sources);
2518
+ visit(flowSettings.destinations);
2519
+ visit(flowSettings.transformers);
2520
+ visit(flowSettings.stores);
2521
+ return namedImports;
2564
2522
  }
2565
- async function generateImportStatements(packages, destinationPackages, sourcePackages, transformerPackages, storePackages, explicitCodeImports, packagePaths, withDev) {
2523
+ async function generateImportStatements(packages, destinationPackages, sourcePackages, transformerPackages, storePackages, namedImports, packagePaths, withDev) {
2566
2524
  const importStatements = [];
2567
2525
  const usedPackages = /* @__PURE__ */ new Set([
2568
2526
  ...destinationPackages,
@@ -2572,21 +2530,21 @@ async function generateImportStatements(packages, destinationPackages, sourcePac
2572
2530
  ]);
2573
2531
  for (const [packageName, packageConfig] of Object.entries(packages)) {
2574
2532
  const isUsedByDestOrSource = usedPackages.has(packageName);
2575
- const hasExplicitCode = explicitCodeImports.has(packageName);
2533
+ const hasNamed = namedImports.has(packageName);
2576
2534
  const namedImportsToGenerate = [];
2577
- if (isUsedByDestOrSource && !hasExplicitCode) {
2535
+ if (isUsedByDestOrSource && !hasNamed) {
2578
2536
  const varName = packageNameToVariable(packageName);
2579
2537
  importStatements.push(`import ${varName} from '${packageName}';`);
2580
2538
  }
2581
- if (hasExplicitCode) {
2582
- const codes = Array.from(explicitCodeImports.get(packageName));
2539
+ if (hasNamed) {
2540
+ const codes = Array.from(namedImports.get(packageName));
2583
2541
  namedImportsToGenerate.push(...codes);
2584
2542
  }
2585
2543
  if (packageConfig.imports && packageConfig.imports.length > 0) {
2586
2544
  const uniqueImports = [...new Set(packageConfig.imports)];
2587
2545
  for (const imp of uniqueImports) {
2588
2546
  if (imp.startsWith("default as ")) {
2589
- if (!isUsedByDestOrSource || hasExplicitCode) {
2547
+ if (!isUsedByDestOrSource || hasNamed) {
2590
2548
  const defaultImportName = imp.replace("default as ", "");
2591
2549
  importStatements.push(
2592
2550
  `import ${defaultImportName} from '${packageName}';`
@@ -2674,7 +2632,7 @@ async function createEntryPoint(flowSettings, buildOptions, packagePaths) {
2674
2632
  const destinationPackages = detectStepPackages(flowSettings, "destinations");
2675
2633
  const transformerPackages = detectStepPackages(flowSettings, "transformers");
2676
2634
  const storePackages = detectStepPackages(flowSettings, "stores");
2677
- const explicitCodeImports = detectExplicitCodeImports(flowSettings);
2635
+ const namedImports = detectNamedImports(flowSettings);
2678
2636
  const storeIds = new Set(Object.keys(flowSettings.stores || {}));
2679
2637
  validateStoreReferences(flowSettings, storeIds);
2680
2638
  if (flowSettings.sources)
@@ -2692,7 +2650,7 @@ async function createEntryPoint(flowSettings, buildOptions, packagePaths) {
2692
2650
  sourcePackages,
2693
2651
  transformerPackages,
2694
2652
  storePackages,
2695
- explicitCodeImports,
2653
+ namedImports,
2696
2654
  packagePaths,
2697
2655
  withDev
2698
2656
  );
@@ -2712,7 +2670,7 @@ ${userCode}` : userCode,
2712
2670
  hasFlow: false
2713
2671
  };
2714
2672
  }
2715
- const { storesDeclaration, codeConfigObject, dataPayload } = buildSplitConfigObject(flowSettings, explicitCodeImports);
2673
+ const { storesDeclaration, codeConfigObject, dataPayload } = buildSplitConfigObject(flowSettings, namedImports);
2716
2674
  const wireConfigModule = generateSplitWireConfigModule(
2717
2675
  storesDeclaration,
2718
2676
  codeConfigObject,
@@ -2751,25 +2709,22 @@ ${firstError.text}`
2751
2709
  ` + (location ? ` at ${location.file}:${location.line}:${location.column}` : "")
2752
2710
  );
2753
2711
  }
2754
- function buildSplitConfigObject(flowSettings, explicitCodeImports) {
2712
+ function buildSplitConfigObject(flowSettings, namedImports) {
2755
2713
  const sources = flowSettings.sources || {};
2756
2714
  const destinations = flowSettings.destinations || {};
2757
2715
  const transformers = flowSettings.transformers || {};
2758
2716
  const stores = flowSettings.stores || {};
2759
2717
  const dataPayloadObj = {};
2760
2718
  function resolveCodeVar(step) {
2761
- if (step.code && typeof step.code === "string" && !step.package) {
2762
- return step.code;
2763
- }
2764
- if (step.code && typeof step.code === "string" && step.package && explicitCodeImports.has(step.package)) {
2765
- return step.code;
2719
+ if (typeof step.import === "string" && step.package) {
2720
+ return step.import;
2766
2721
  }
2767
2722
  return packageNameToVariable(step.package);
2768
2723
  }
2769
2724
  function getStepProps(step) {
2770
2725
  const props = {};
2771
2726
  for (const [key, value] of Object.entries(step)) {
2772
- if (key === "code" || key === "package") continue;
2727
+ if (key === "code" || key === "package" || key === "import") continue;
2773
2728
  if (value !== void 0 && value !== null) {
2774
2729
  props[key] = value;
2775
2730
  }
@@ -2819,12 +2774,12 @@ function buildSplitConfigObject(flowSettings, explicitCodeImports) {
2819
2774
  return buildSplitStepEntry("destinations", key, dest);
2820
2775
  });
2821
2776
  const transformersEntries = Object.entries(transformers).filter(
2822
- ([, transformer]) => transformer.package || hasCodeReference(transformer.code) || isPathTransformerEntry({ ...transformer })
2777
+ ([, transformer]) => transformer.package || hasCodeReference(transformer.code) || isPathStepEntry({ ...transformer }, "Transformer")
2823
2778
  ).map(([key, transformer]) => {
2824
2779
  if (isInlineCode(transformer.code)) {
2825
2780
  return ` ${key}: ${generateInlineCode(transformer.code, transformer.config || {}, transformer.env, { before: transformer.before, next: transformer.next })}`;
2826
2781
  }
2827
- if (isPathTransformerEntry({ ...transformer })) {
2782
+ if (isPathStepEntry({ ...transformer }, "Transformer")) {
2828
2783
  const chainLines = [];
2829
2784
  if (transformer.before !== void 0) {
2830
2785
  chainLines.push(`before: ${JSON.stringify(transformer.before)}`);
@@ -3622,16 +3577,13 @@ import fs15 from "fs-extra";
3622
3577
  import {
3623
3578
  createIngest,
3624
3579
  getPlatform as getPlatform3,
3625
- compileNext,
3626
- resolveNext,
3580
+ getNextSteps,
3627
3581
  buildCacheContext
3628
3582
  } from "@walkeros/core";
3629
3583
  import {
3630
3584
  transformerInit,
3631
3585
  transformerPush,
3632
3586
  runTransformerChain,
3633
- walkChain,
3634
- extractTransformerNextMap,
3635
3587
  wrapEnv
3636
3588
  } from "@walkeros/collector";
3637
3589
 
@@ -4318,14 +4270,39 @@ async function runDestinationSimulationLoop(config, event, destinationIds, optio
4318
4270
  function isRecord(value) {
4319
4271
  return value !== null && typeof value === "object";
4320
4272
  }
4273
+ function isString(value) {
4274
+ return typeof value === "string";
4275
+ }
4276
+ function walkStaticChain(startId, transformers) {
4277
+ const chain = [];
4278
+ const visited = /* @__PURE__ */ new Set();
4279
+ let current = startId;
4280
+ while (current && transformers[current]) {
4281
+ if (visited.has(current)) break;
4282
+ visited.add(current);
4283
+ chain.push(current);
4284
+ const next = transformers[current].config?.next;
4285
+ if (typeof next === "string") {
4286
+ current = next;
4287
+ continue;
4288
+ }
4289
+ if (Array.isArray(next) && next.every(isString)) {
4290
+ chain.push(...next);
4291
+ break;
4292
+ }
4293
+ break;
4294
+ }
4295
+ return chain;
4296
+ }
4321
4297
  function resolveBeforeChain(before, transformers, ingest, event) {
4322
4298
  if (!before) return [];
4323
- const resolved = resolveNext(
4324
- compileNext(before),
4325
- buildCacheContext(ingest, event)
4326
- );
4327
- if (!resolved) return [];
4328
- return walkChain(resolved, extractTransformerNextMap(transformers));
4299
+ if (Array.isArray(before) && before.every(isString)) {
4300
+ return before;
4301
+ }
4302
+ const ids = getNextSteps(before, buildCacheContext(ingest, event));
4303
+ if (ids.length === 0) return [];
4304
+ if (ids.length === 1) return walkStaticChain(ids[0], transformers);
4305
+ return ids;
4329
4306
  }
4330
4307
  async function pushCore(inputPath, event, options = {}) {
4331
4308
  const logger = createCLILogger({
@@ -6049,11 +6026,7 @@ function validateEvent2(input) {
6049
6026
  }
6050
6027
 
6051
6028
  // src/commands/validate/validators/flow.ts
6052
- import {
6053
- getFlowSettings as getFlowSettings2,
6054
- isObject as isObject2,
6055
- validateTransformerEntry as validateTransformerEntry2
6056
- } from "@walkeros/core";
6029
+ import { getFlowSettings as getFlowSettings2, isObject as isObject2, validateStepEntry as validateStepEntry2 } from "@walkeros/core";
6057
6030
  import { schemas as schemas4 } from "@walkeros/core/dev";
6058
6031
  var { validateFlowConfig: validateFlowConfig2 } = schemas4;
6059
6032
  function isFlowJson(value) {
@@ -6109,7 +6082,7 @@ function validateFlow(input, options = {}) {
6109
6082
  transformersValue
6110
6083
  )) {
6111
6084
  if (!isObject2(transformerValue)) continue;
6112
- const result = validateTransformerEntry2(transformerValue);
6085
+ const result = validateStepEntry2(transformerValue, "Transformer");
6113
6086
  if (!result.ok) {
6114
6087
  errors.push({
6115
6088
  path: `flows.${flowName}.transformers.${name}`,
@@ -6206,6 +6179,15 @@ function validateFlow(input, options = {}) {
6206
6179
  }
6207
6180
  }
6208
6181
  }
6182
+ if (errors.length === 0 && isFlowJson(input)) {
6183
+ const typedFlows = input.flows;
6184
+ const flowsToLint = options.flow ? options.flow in typedFlows ? [options.flow] : [] : Object.keys(typedFlows);
6185
+ for (const name of flowsToLint) {
6186
+ const flowSettings = typedFlows[name];
6187
+ if (!flowSettings) continue;
6188
+ lintFlowRoutes(name, flowSettings, warnings);
6189
+ }
6190
+ }
6209
6191
  if (errors.length === 0 && isFlowJson(input)) {
6210
6192
  const flowsMap = input.flows;
6211
6193
  const flowsToResolve = options.flow ? options.flow in flowsMap ? [options.flow] : [] : Object.keys(flowsMap);
@@ -6239,31 +6221,42 @@ function validateFlow(input, options = {}) {
6239
6221
  details
6240
6222
  };
6241
6223
  }
6224
+ function isRouteConfig(spec) {
6225
+ return typeof spec === "object" && spec !== null && !Array.isArray(spec);
6226
+ }
6227
+ function isRouteNext(spec) {
6228
+ if (!("next" in spec)) return false;
6229
+ const value = spec.next;
6230
+ return value !== void 0;
6231
+ }
6232
+ function isRouteOne(spec) {
6233
+ if (!("one" in spec)) return false;
6234
+ const value = spec.one;
6235
+ return Array.isArray(value);
6236
+ }
6237
+ function isRouteMany(spec) {
6238
+ if (!("many" in spec)) return false;
6239
+ const value = spec.many;
6240
+ return Array.isArray(value);
6241
+ }
6242
6242
  function flattenRouteTargets(spec) {
6243
6243
  if (!spec) return [];
6244
6244
  if (typeof spec === "string") return [spec];
6245
- if (!Array.isArray(spec) && typeof spec === "object") {
6246
- const cfg = spec;
6247
- if ("next" in cfg && cfg.next !== void 0)
6248
- return flattenRouteTargets(cfg.next);
6249
- if ("case" in cfg && cfg.case) {
6250
- return Array.from(new Set(cfg.case.flatMap(flattenRouteTargets)));
6245
+ if (isRouteConfig(spec)) {
6246
+ if (isRouteNext(spec)) return flattenRouteTargets(spec.next);
6247
+ if (isRouteOne(spec)) {
6248
+ return Array.from(new Set(spec.one.flatMap(flattenRouteTargets)));
6249
+ }
6250
+ if (isRouteMany(spec)) {
6251
+ return Array.from(new Set(spec.many.flatMap(flattenRouteTargets)));
6251
6252
  }
6252
6253
  return [];
6253
6254
  }
6254
- if (Array.isArray(spec) && spec.length === 0) return [];
6255
+ if (spec.length === 0) return [];
6255
6256
  if (typeof spec[0] === "string") {
6256
6257
  return spec.filter((s) => typeof s === "string");
6257
6258
  }
6258
- return Array.from(
6259
- new Set(
6260
- spec.flatMap(
6261
- (entry) => flattenRouteTargets(
6262
- entry
6263
- )
6264
- )
6265
- )
6266
- );
6259
+ return Array.from(new Set(spec.flatMap(flattenRouteTargets)));
6267
6260
  }
6268
6261
  function buildConnectionGraph(config) {
6269
6262
  const connections = [];
@@ -6366,6 +6359,89 @@ function isStructurallyCompatible(a, b) {
6366
6359
  }
6367
6360
  return true;
6368
6361
  }
6362
+ function lintFlowRoutes(flowName, flow, warnings) {
6363
+ for (const [name, source] of Object.entries(flow.sources || {})) {
6364
+ lintRoute(source.next, `flows.${flowName}.sources.${name}.next`, warnings);
6365
+ lintRoute(
6366
+ source.before,
6367
+ `flows.${flowName}.sources.${name}.before`,
6368
+ warnings
6369
+ );
6370
+ }
6371
+ for (const [name, transformer] of Object.entries(flow.transformers || {})) {
6372
+ lintRoute(
6373
+ transformer.next,
6374
+ `flows.${flowName}.transformers.${name}.next`,
6375
+ warnings
6376
+ );
6377
+ lintRoute(
6378
+ transformer.before,
6379
+ `flows.${flowName}.transformers.${name}.before`,
6380
+ warnings
6381
+ );
6382
+ }
6383
+ for (const [name, dest] of Object.entries(flow.destinations || {})) {
6384
+ lintRoute(
6385
+ dest.before,
6386
+ `flows.${flowName}.destinations.${name}.before`,
6387
+ warnings
6388
+ );
6389
+ lintRoute(
6390
+ dest.next,
6391
+ `flows.${flowName}.destinations.${name}.next`,
6392
+ warnings
6393
+ );
6394
+ }
6395
+ }
6396
+ function lintRoute(spec, position, warnings) {
6397
+ if (!spec) return;
6398
+ if (typeof spec === "string") return;
6399
+ if (Array.isArray(spec)) {
6400
+ for (let i = 0; i < spec.length; i++) {
6401
+ const entry = spec[i];
6402
+ if (i < spec.length - 1 && typeof entry === "object" && entry !== null && !Array.isArray(entry) && isRouteMany(entry)) {
6403
+ warnings.push({
6404
+ path: position,
6405
+ message: `dead code after many at ${position}: main chain terminates at the many operator`,
6406
+ suggestion: "Remove entries after the many operator; move them into each many branch if they should still run."
6407
+ });
6408
+ }
6409
+ lintRoute(entry, `${position}[${i}]`, warnings);
6410
+ }
6411
+ return;
6412
+ }
6413
+ if (isRouteNext(spec)) {
6414
+ lintRoute(spec.next, `${position}.next`, warnings);
6415
+ return;
6416
+ }
6417
+ if (isRouteOne(spec)) {
6418
+ for (let i = 0; i < spec.one.length; i++) {
6419
+ lintRoute(spec.one[i], `${position}.one[${i}]`, warnings);
6420
+ }
6421
+ return;
6422
+ }
6423
+ if (isRouteMany(spec)) {
6424
+ if (spec.many.length === 0) {
6425
+ warnings.push({
6426
+ path: position,
6427
+ message: `empty many at ${position}: main chain terminates with no branches; use next or remove`,
6428
+ suggestion: "Add one or more branch targets to many, or replace many with next if no fan-out is needed."
6429
+ });
6430
+ } else if (spec.many.length === 1) {
6431
+ const only = spec.many[0];
6432
+ const hint = typeof only === "string" ? `use 'next: "${only}"' for clarity` : `use 'next' for clarity`;
6433
+ warnings.push({
6434
+ path: position,
6435
+ message: `single-entry many at ${position}: ${hint}`,
6436
+ suggestion: "Replace many with next when only one branch exists."
6437
+ });
6438
+ }
6439
+ for (let i = 0; i < spec.many.length; i++) {
6440
+ lintRoute(spec.many[i], `${position}.many[${i}]`, warnings);
6441
+ }
6442
+ return;
6443
+ }
6444
+ }
6369
6445
  function checkContractCompliance(config, contract, warnings) {
6370
6446
  for (const [name, dest] of Object.entries(config.destinations || {})) {
6371
6447
  if (!dest.examples) continue;
@@ -6452,7 +6528,7 @@ function validateMapping(input) {
6452
6528
  // src/commands/validate/validators/entry.ts
6453
6529
  import Ajv from "ajv";
6454
6530
  import { fetchPackageSchema } from "@walkeros/core";
6455
- var CLIENT_HEADER = "walkeros-cli/4.1.0-next-1778668930820";
6531
+ var CLIENT_HEADER = "walkeros-cli/4.1.0";
6456
6532
  var SECTIONS = ["destinations", "sources", "transformers"];
6457
6533
  function resolveEntry(path20, flowConfig) {
6458
6534
  const flows = flowConfig.flows;