@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/CHANGELOG.md +33 -5
- package/README.md +21 -712
- package/dist/cli.js +2263 -1811
- package/dist/examples/README.md +6 -8
- package/dist/examples/flow-complete.json +1 -19
- package/dist/examples/flow-complete.md +10 -13
- package/dist/examples/index.js +1 -19
- package/dist/examples/index.js.map +1 -1
- package/dist/examples/server-collect.json +2 -2
- package/dist/index.js +191 -115
- package/dist/index.js.map +1 -1
- package/examples/README.md +6 -8
- package/examples/flow-complete.json +1 -19
- package/examples/flow-complete.md +10 -13
- package/examples/server-collect.json +2 -2
- package/package.json +7 -7
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
|
-
|
|
1901
|
-
|
|
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 =
|
|
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.
|
|
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
|
|
2506
|
-
const
|
|
2507
|
-
const
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
2533
|
+
const hasNamed = namedImports.has(packageName);
|
|
2576
2534
|
const namedImportsToGenerate = [];
|
|
2577
|
-
if (isUsedByDestOrSource && !
|
|
2535
|
+
if (isUsedByDestOrSource && !hasNamed) {
|
|
2578
2536
|
const varName = packageNameToVariable(packageName);
|
|
2579
2537
|
importStatements.push(`import ${varName} from '${packageName}';`);
|
|
2580
2538
|
}
|
|
2581
|
-
if (
|
|
2582
|
-
const codes = Array.from(
|
|
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 ||
|
|
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
|
|
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
|
-
|
|
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,
|
|
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,
|
|
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 (
|
|
2762
|
-
return step.
|
|
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) ||
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
);
|
|
4327
|
-
if (
|
|
4328
|
-
return
|
|
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 =
|
|
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 (
|
|
6246
|
-
|
|
6247
|
-
if (
|
|
6248
|
-
return
|
|
6249
|
-
|
|
6250
|
-
|
|
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 (
|
|
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
|
|
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;
|